【问题标题】:How can I check that multiple async operations have completed?如何检查多个异步操作是否已完成?
【发布时间】:2017-05-30 12:37:22
【问题描述】:

我有一个案例,我想在 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?

我怎样才能做到这一点?

【问题讨论】:

  • 你能把你的问题标记为javascript吗?

标签: javascript promise rxjs


【解决方案1】:

这取决于你是否事先知道异步操作(读取 Observables/Promises)。

例如,如果您可以组成一个 Observables 数组,那么最简单的方法是使用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'));

【讨论】:

    【解决方案2】:

    'Rx 方式'是使用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));
    

    【讨论】:

      【解决方案3】:

      您必须使循环异步,以便仅在下一个响应可用时才会发生迭代。您可以这样做:

      (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 具有相同的值。

      请注意,这种异步处理也可以通过 Promise 和一些最近的功能(如 asyncawait)来完成。你可能想调查一下。 Here is an example

      【讨论】:

        【解决方案4】:

        您可以只计算单独变量中的响应,并在继续之前检查它:

        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);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-11-13
          • 1970-01-01
          • 2015-01-07
          • 2014-07-22
          • 1970-01-01
          相关资源
          最近更新 更多