如何检查多个异步操作是否已完成?

时间:2017-05-30 12:37:23

标签: javascript promise rxjs

我有一个案例,我希望在完成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?

我怎样才能做到这一点?

4 个答案:

答案 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和一些最近的功能来完成,例如asyncawait。你可能想看一下。 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);
相关问题