在完成所有异步回调之后,每个回调都完成了

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (13)

whenAllDone()在执行forEach-循环之后,对每个元素进行了遍历,并进行了一些异步处理。

[1, 2, 3].forEach(
  function(item, index, array, done) {
     asyncFunction(item, function itemDone() {
       console.log(item + " done");
       done();
     });
  }, function allDone() {
     console.log("All done");
     whenAllDone();
  }
);

能让它像这样工作吗?当用于Each的第二个参数是一个回调函数时,它会在所有迭代过程中运行吗?

预期产出:

3 done
1 done
2 done
All done!
提问于
用户回答回答于

Array.forEach没有提供这种精确性(如果可以的话),但是有几种方法可以实现想要的:

使用简单计数器

function callback () { console.log('all done'); }

var itemsProcessed = 0;

[1, 2, 3].forEach((item, index, array) => {
  asyncFunction(item, () => {
    itemsProcessed++;
    if(itemsProcessed === array.length) {
      callback();
    }
  });
});

保证在调用“已完成”回调之前处理所有项。Emil建议的方法,虽然在我的经验中通常是有效的,但没有提供同样的保证。

使用ES6承诺

(承诺库可用于较旧的浏览器):

  1. 处理所有保证同步执行的请求(例如1、2、3) 函数异步函数(Item,CB){setTimeout(()=>{sole e.log)(“完成”,Item);CB();},100);}let requents=1,2,3.减((proexeChain,Item)=>{ReverizeChain.so(())=>新的承诺((Resolate)=>{异步函数(Item,Resolate);});},Promise.Resolate();requests.so()=>控制台.log(‘do’)
  2. 处理所有异步请求而不执行“同步”(2可能比1更快) 让请求=1,2,3.map((项目)=>{返回新的承诺((解决)=>{异步函数(项目,解析);})Promise.all(请求)。然后(()=>控制台.log(‘完成’));

问题的主体已经被编辑,以删除以前的同步示例代码,所以我更新了我的答案以澄清。原始示例使用同步代码来建模异步行为,因此应用了以下方法:

array.forEach是同步也是如此res.write,这样就可以简单地将回调放在调用之后,以便预先执行:

  posts.foreach(function(v, i) {
    res.write(v + ". index " + i);
  });

  res.end();
用户回答回答于

如果遇到异步函数,并且希望确保在执行代码之前它完成了任务,那么我们始终可以使用回调功能。

例如:

var ctr = 0;
posts.forEach(function(element, index, array){
    asynchronous(function(data){
         ctr++; 
         if (ctr === array.length) {
             functionAfterForEach();
         }
    })
});

注意:FunctionAfterForEach是在Foreach任务完成后执行的函数。异步是在foreach中执行的异步函数。

扫码关注云+社区