如何在循环中返回多个(并行)异步函数调用的累积结果? [英] How do I return the accumulated results of multiple (parallel) asynchronous function calls in a loop?

查看:199
本文介绍了如何在循环中返回多个(并行)异步函数调用的累积结果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数 foo ,它在循环中进行多个(并行)异步调用。我需要等到所有呼叫的结果都可用。如何从 foo 返回完整结果,或者在所有数据可用后触发某些处理?

I have a function foo which makes multiple (parallel) asynchronous calls in a loop. I need to somehow wait until the results of all of the calls are available. How can I return the full results from foo, or otherwise trigger some processing after all of the data is available?

我尝试将每个结果添加到数组中,但是直到我需要使用它之后才会填充数组。

I tried adding each result to an array, but then the array isn't populated until after the point where I need to use it.

function foo() {
    var results = [];

    for (var i = 0; i < 10; i++) {
      someAsyncFunction({someParam:i}, function callback(data) {
        results.push(data);
      });
    }
    return results;
}

var result = foo(); // It always ends up being an empty array at this point.

注意:这个问题是按照现有通用如何从异步调用中返回响应?问题。这个问题有一些很好的答案,但不包括多个异步调用。还有一些其他问题提到多个调用,但我找不到任何基于循环的调用,有些只有jQuery答案等等。我希望这里有一些不依赖于特定库的通用技术。

Note: this question is deliberately generic along the lines of the existing generic "How do I return the response from an asynchronous call?" question. That question has some excellent answers, but doesn't cover multiple async calls. There are some other questions that mention multiple calls, but I couldn't find any loop-based ones, and some only had jQuery answers, etc. I'm hoping here for some generic techniques that don't depend on a particular library.

推荐答案

使用promises。准确地说, Promise.all 就是为此设计的。

Use promises. Precisely, Promise.all was designed for this.

它接受一个数组(或可迭代)的promises,并返回一个新的promise,当阵列的所有承诺都已解决。否则,它拒绝任何数组的承诺拒绝。

It takes an array (or iterable) of promises, and returns a new promise which is resolved when all the promises of the array have been resolved. Otherwise, it rejects when any promise of the array rejects.

function someAsyncFunction(data, resolve, reject) {
  setTimeout(function() {
    if(Math.random() < .05) {
      // Suppose something failed
      reject('Error while processing ' + data.someParam);
    } else {
      // Suppose the current async work completed succesfully
      resolve(data.someParam);
    }
  }, Math.random() * 1000);
}

function foo() {
  
  // Create an array of promises
  var promises = [];
  
  for (var i = 0; i < 10; i++) {
    // Fill the array with promises which initiate some async work
    promises.push(new Promise(function(resolve, reject) {
      someAsyncFunction({someParam:i}, resolve, reject);
    }));
  }
  
  // Return a Promise.all promise of the array
  return Promise.all(promises);
}

var result = foo().then(function(results) {
  console.log('All async calls completed successfully:');
  console.log(' --> ', JSON.stringify(results));
}, function(reason) {
  console.log('Some async call failed:');
  console.log(' --> ', reason);
});

请注意,结果将根据到承诺数组的顺序,而不是承诺被解决的顺序。

Note that the results will be given according to the order of the array of promises, not in the order that the promises were resolved in.

这篇关于如何在循环中返回多个(并行)异步函数调用的累积结果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆