【问题标题】:Calling JavaScript async function in for loop在 for 循环中调用 JavaScript 异步函数
【发布时间】:2017-12-16 00:13:48
【问题描述】:

我有一个for 循环,我想在每次迭代时调用一个异步函数。但是我收到了一个 JS 堆栈跟踪错误。下面是我的代码原型。我也使用过 IIFE 模式,但它不起作用。

for(let i = 0; i<99999;i++){
  getData(i, function(err, result){
      if(err) return err;
      else{
       console.log(result);
      }
  });
}
function getData(number, callback){
  request('http://someapiurl'+number, function(err, response){
     if(err) callback(err, null);
     else{
      callback(null, response)
     }
  })
}

【问题讨论】:

  • 如果要等待getData的结果再执行循环的下一次迭代,则不能使用for循环。

标签: javascript asynchronous


【解决方案1】:

您正在尝试同时制作 99999,这在大多数浏览器上都不起作用。

改用 Promise,将它们推送到数组中,然后使用 Promise.all 让浏览器处理请求,简单地处理最终解析的响应。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
}); 

Promise.all([p1, p2, p3]).then(values => { 
  console.log(values); // [3, 1337, "foo"] 
});

【讨论】:

    【解决方案2】:

    首先,我强烈建议您调试代码以准确了解 for 循环会发生什么。

    很可能循环在其内容(getData 函数)执行之前完全运行,通过获取数据请求的异步行为。如果您尝试使用 IIFE 模式,您至少已经将内容包装在您的 for 循环中,以保证其内容能够执行。一个实现示例如下所示:

    for(let i = 0; i<99999;i++){
      (function(){ // <-- IIFE used to represent a closure.
        getData(i, function(err, result){
          if(err) return err;
            else{
              console.log(result);
            }
        });
      })(i);
    }
    

    @mika 坐在为您承诺的主题上,您可以阅读他们的回答;只要记住诺言反模式,你会没事的。如果您不习惯 Promise 并希望在 for 循环中使用它们,这尤其棘手。

    【讨论】:

      猜你喜欢
      • 2012-10-31
      • 2011-12-03
      • 1970-01-01
      • 2014-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-11
      • 2015-11-14
      相关资源
      最近更新 更多