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

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

问题描述

正如标题。我该怎么做呢?

我要打电话 whenAllDone()后的foreach循环经历的每个元素消失了,做了一些异步处理。

  [1,2,3] .forEach(
  函数(项目,指标,数组完成){
     asyncFunction(项目,功能itemDone(){
       的console.log(项目+完成);
       完成();
     });
  },功能allDone(){
     的console.log(所有做);
     whenAllDone();
  }
);

有可能得到它像这样的工作吗?当第二个参数的forEach是它运行,一旦通过所有迭代了一个回调函数?

期望的输出:

  3 DONE
1 DONE
2 DONE
全做完了!


解决方案

Array.forEach 不提供这种精密(哦,它是否会),但有几种方法完成你想要的:

使用一个简单的计数器

 回调函数(){的console.log('全部完成'); }变种itemsProcessed = 0;[1,2,3] .forEach((项目,索引,阵列)= GT; {
  asyncFunction(项目,()=> {
    itemsProcessed ++;
    如果(itemsProcessed === array.length){
      回电话();
    }
  });
});

(感谢@vanuan等)这种方法可以保证所有的项目调用完成回调之前处理。爱弥尔建议,而通常在我的经验有效的方法,不能提供同样的保证。

使用ES6少辉

(一个承诺库,可用于旧的浏览器):


  1. 工艺,保证同步执行的所有请求(例如1然后2然后3)

     函数asyncFunction(项目,CB){
      的setTimeout(()=> {
        的console.log('与做,项目);
        CB();
      },100);
    }让请求= [1,2,3]。降低((promiseChain,项目)= GT; {
        返回promiseChain.then(()=>新建无极((解析)=> {
          asyncFunction(项目,解决);
        }));
    },Promise.resolve());requests.then(()=>的console.log('完成'))


  2. 过程中无同步执行中的所有异步请求(2可以完成的速度比1)

     让请求= [1,2,3] .MAP((项目)=> {
        返回新希望((解析)=> {
          asyncFunction(项目,解决);
        });
    })Promise.all(请求)。然后(()=>的console.log('完成'));


使用异步库

有其它异步库,异步是最流行的,能够提供你想要什么样的机制来恩preSS。

编辑

问题的身体已被编辑删除了previously同步例如code,所以我已经更新了我的回答澄清。
像code最初的例子使用同步建模异步行为,所以下面的应用:

array.forEach ,所以是 res.write ,所以你可以简单地把你的回调您的来电后的foreach:

  posts.foreach(函数(V,I){
    res.write(V +。指数+ I);
  });  重发();

As the title suggests. How do I do this?

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

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

Expected output:

3 done
1 done
2 done
All done!

解决方案

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

Using a simple counter

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

var itemsProcessed = 0;

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

(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.

Using ES6 Promises

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

  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. 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'));
    

Using an async library

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

Edit

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 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天全站免登陆