【问题标题】:for loop exit before callback is finished回调完成前for循环退出
【发布时间】:2017-03-05 21:36:38
【问题描述】:

我有一个调用异步函数的 for 循环。我需要这个函数然后在 for 循环结束时调用一个回调,但只有当我所有的异步函数都返回了它们的结果时。我试过这个:

for(var i = 0; i < vaccinsCount; i++){
    getVaccinAddress(i, address, provider, function(result){
       if(result.success){
         console.log("result:" + result.values);
         vaccines.push(result.values);
       } else {
         callback({success: false, message: result.message}); 
       }
   });
}
callback({success: true, values: vaccines}); 

相反,代码进入 for 循环,然后调用异步函数,然后直接退出。我怎么能解决这个问题?

getVaccinAddress 是执行服务器调用的异步函数。

编辑

我正在使用 NodeJS,因此解决方案是使用 bluebird,但是我不知道如何使用 bluebird 来实现。

【问题讨论】:

  • 搜索 SO 和 google for loop async
  • 我有,但我仍然不明白如何让它工作。
  • 您的代码不完整,getVaccinAddress 函数中有什么?
  • 它是异步函数。
  • 如果getVaccinAddress()抛出错误或者result.success不是true会发生什么?

标签: javascript asynchronous callback bluebird


【解决方案1】:

我强烈建议在这种情况下使用 Promise。 这是管理异步调用的好方法: https://davidwalsh.name/promises

如果您使用 Promise,您的代码将如下所示:

var promises = []
for(var i = 0; i < vaccinsCount; i++){
    promises.push(getVaccinAddress(i, address, provider));
    // getVaccinAddress will need to return a promise
}

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

【讨论】:

  • 我虽然关于使用 Promis 但我在 NodeJS 中编码,因此我不确定如何使这项工作。
  • @Rémi 使用 Bluebirdjs
  • 如果你使用 NodeJS 那就更好了。安装 bluebird,它比标准 Promise 快得多:bluebirdjs.com/docs/getting-started.html
  • 好吧,我会使用 bleubird,它看起来更容易,但我仍然不知道如何在 bleubird 中实现它。
  • 使用Promisevaccines.length === vaccinsCount时执行动作有什么区别?
【解决方案2】:

vaccines.length等于vaccinsCount时,你可以调用callback()

for(var i = 0; i < vaccinsCount; i++) {
  (function(i) {
    getVaccinAddress(i, address, provider, function(result) {
       if(result.success) {
         console.log("result:" + result.values);
         vaccines.push(result.values);
         if (vaccines.length === vaccinsCount) {
            // call `callback()` here
         }            
       }
    });
  })(i);
} 

【讨论】:

  • 我已经尝试过了,但代码永远不会进入 if(vaccines.lenght === vaccinesCOunt)
  • @Rémi “我已经尝试过了,但代码从未进入 if(vaccines.lenght === vaccinesCOunt)” 这就是为什么询问预期结果是什么,如果错误发生或result.success 不会评估为true,这可能是vaccines.length === vaccinsCount 不会评估为true 的原因之一。如果i 等于vaccinsCount,您也可以调用callback,而不管result.success 的计算结果是否为true。是否记录了任何错误? result.success true 是否适用于对getVaccinAddress 的所有调用?
猜你喜欢
  • 1970-01-01
  • 2019-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 1970-01-01
  • 2018-05-12
  • 2011-01-22
相关资源
最近更新 更多