正如标题所暗示的那样.我该怎么做呢?
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 没有提供这个细节(如果有的话)但是有几种方法可以完成你想要的:
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 和其他人)这种方法保证在调用完成"回调之前处理所有项目.您需要使用在回调中更新的计数器.依赖于索引参数的值不提供相同的保证,因为异步操作的返回顺序是没有保证的.
(thanks to @vanuan and others) This approach guarantees that all items are processed before invoking the "done" callback. You need to use a counter that gets updated in the callback. Depending on the value of the index parameter does not provide the same guarantee, because the order of return of the asynchronous operations is not guaranteed.
(promise 库可用于旧浏览器):
(a promise library can be used for older browsers):
处理所有保证同步执行的请求(例如 1 然后 2 然后 3)
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 回调完成后的回调
发布评论