我有一个案例,我希望在完成10次异步调用后做一些事情
let i = 0;
let array = [];
do {
this.service.getSomething(i).subscribe(response => {
array[i] = response;
});
} while (i < 10);
// how can I know when the 10 async calls have completed?
我怎样才能做到这一点?
答案 0 :(得分:2)
这取决于您是否事先知道异步操作(读取Observables / Promises)。
例如,如果你可以编写一个Observable数组,那么最简单的方法是使用forkJoin
:
let observables = [ ... ];
Observable.forkJoin(observables)
.subscribe(results => /* whatever */);
否则,您可以mergeMap
将它们放入单个链中,只收听complete
信号:
Observable.range(1, 10) // or whatever
.mergeMap(i => /* return Observable here */)
.subscribe(undefined, undefined, () => console.log('all done'));
答案 1 :(得分:1)
&#39; Rx方式&#39;是使用forkJoin:
const requestParams = [0,1,2,3,4,5,6,7,8,9];
const requests = requestParams.map(i => this.service.getSomething(i));
Observable.forkJoin(requests).subscribe(reponseArray => alldone(responseArray));
答案 2 :(得分:0)
您必须使您的循环异步,以便只有在下一个响应可用时才会发生迭代。以下是如何做到这一点:
(function loop(arr) {
if (arr.length >= 10) return alldone(array); // all done
this.service.getSomething(arr.length).subsribe(response => {
loop(array.concat(response)); // "recursive" call
});
})([]); // <--- pass empty array as argument to the loop function
function alldone(arr) {
console.log(arr);
}
使用空数组作为参数立即调用loop
函数。当你得到响应时,你再次调用该函数,现在使用扩展数组,...等。一旦有10个响应,就可以调用另一个函数来完成最终数组。
如您所见,我选择删除变量i
,因为arr.length
具有相同的值。
请注意,这种异步处理也可以使用promises和一些最近的功能来完成,例如async
和await
。你可能想看一下。 this answer
答案 3 :(得分:0)
您可以在单独的变量中计算响应,并在继续之前检查它:
let i = 0;
let array = [];
var finishedCnt=0;
do {
this.service.getSomething(i).subsribe(response => {
array[i] = response;
finishedCnt++;
if(finishedCnt>=10) {
// all requests done, do something here
}
});
} while (i < 10);