所有异步forEach回调完成后的回调 [英] Callback after all asynchronous forEach callbacks are completed

查看:3576
本文介绍了所有异步forEach回调完成后的回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如标题所示。我如何做到这一点?

As the title suggests. How do I do this?

在forEach循环遍历每个元素并完成一些异步处理后,我想调用 whenAllDone()

I want to call whenAllDone() after the forEach-loop has gone through each element and done some asynchronous processing.

[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();
  }
);

可以让它像这样工作吗?当forEach的第二个参数是一个经过所有迭代运行的回调函数?

Possible to get it to work like this? When the second argument to forEach is a callback function which runs once it went through all iterations?

预期输出:

3 done
1 done
2 done
All done!


推荐答案

Array.forEach 不提供这个nicety(哦,如果它会),但有几种方法来完成你想要的:

Array.forEach does not provide this nicety (oh if it would) but there are several ways to accomplish what you want:

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

var itemsProcessed = 0;

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

(感谢@vanuan和其他人)这种方法保证所有项目在调用done 回电话。 Emil建议的方法虽然在我的经验中通常很有效,但不能提供相同的保证。

(thanks to @vanuan and others) This approach guarantees that all items are processed before invoking the "done" callback. The approach that Emil suggests, while typically effective in my experience, does not provide the same guarantee.

(promise库可用于旧版浏览器):

(a promise library can be used for older browsers):


  1. 处理所有要求同步执行的请求2 then 3)

  1. Process all requests guaranteeing synchronous execution (e.g. 1 then 2 then 3)

function asyncFunction (item, cb) {
  setTimeout(() => {
    console.log('done with', item);
    cb();
  }, 100);
}

let requests = [1, 2, 3].reduce((promiseChain, item) => {
    return promiseChain.then(() => new Promise((resolve) => {
      asyncFunction(item, resolve);
    }));
}, Promise.resolve());

requests.then(() => console.log('done'))


  • 处理所有异步请求,没有同步执行(2可能比1快)

  • Process all async requests without "synchronous" execution (2 may finish faster than 1)

    let requests = [1,2,3].map((item) => {
        return new Promise((resolve) => {
          asyncFunction(item, resolve);
        });
    })
    
    Promise.all(requests).then(() => console.log('done'));
    




  • 使用异步库



    还有其他异步库, async 是最流行的,提供了表达什么的机制

    Using an async library

    There are other asynchronous libraries, async being the most popular, that provide mechanisms to express what you want.

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

    The body of the question has been edited to remove the previously synchronous example code, so i've updated my answer to clarify. The original example used synchronous like code to model asynchronous behaviour, so the following applied:

    array.forEach 同步,因此是 res.write ,因此您可以简单地把你的回调调用后的foreach:

    array.forEach is synchronous and so is res.write, so you can simply put your callback after your call to foreach:

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

    这篇关于所有异步forEach回调完成后的回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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