从循环运行异步函数

时间:2017-04-07 15:58:11

标签: javascript asynchronous design-patterns

我不是在寻找任何特定语言的解决方案,我只是想了解在循环中运行异步任务方面的优秀做法。

这是我到目前为止所想到的:

var callAcc = 0;
var resultArr = [];

for (var k = 0; k < 20; k++) {
    callAcc ++;

    asyncFunction("variable")
        .then(function (result) {
            resultArr.push(result);

            if (callAcc === resultArr.length) {
                // do something with the resultArr
            }
        })
        .catch(function (err) {
           console.warn(err);
        });
}

此时,我只是使用一个同步变量,只有在完成所有异步任务后才能让我继续。然而,这感觉很hacky,我想知道是否有某种设计模式从循环执行异步任务

修改 根据提出的解决方案,这就是我最终使用

var promises = []; 
for (var i = 0; i < 20; i ++) { 
    promises.push(asyncFunction("param")); 
} 

Promise.all(promises) 
   .then(function (result) { 
     console.log(result); 
   })
   .catch(function (err) { 
     console.warn(err); 
   });

谢谢大家!

1 个答案:

答案 0 :(得分:2)

不是在循环中运行异步任务,而是使用Promise.all函数抽象等待所有承诺的任务,这将承担您的承诺的可迭代并创建一个新的承诺,只要所有结果都解析,就返回一个数组,其所有结果的顺序与原始的promises列表相同,如果其中任何一个失败,则返回失败。大多数拥有Promise的语言都有这样的功能,如果没有,那么定义它应该不会太难。

如果您需要运行所有承诺,即使它们中的任何一个失败,您也可以编写一个执行该功能的函数,您只需要定义如何处理失败的Promises(丢弃它们,返回错误)不知何故...)。

无论如何,它的要点是处理多个Promise编排的最佳方法是定义一个函数,它将接受你需要处理的所有Promise并返回一个新的Promise来处理编排。

类似的东西:

orchestratePromises(promiseList) {
  return new Promise((resolve, reject) => {
    // set up
    for (let promise of promiseList) {
      // define how to handle your promises when they resolve
      // asynchronously resolve or reject
    }
  }
}