正如标题所示.我该怎么做?

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

[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的第二个参数是一个回调函数,它在所有迭代中运行一次?

预期输出:

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

(感谢@vanuan和其他人)这种方法保证在调用"done"回调之前处理所有项.您需要使用在回调中更新的计数器.取决于索引参数的值,它不能提供相同的保证,因为异步操作的返回顺序不能保证.

使用ES6promise

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

  1. 处理所有保证同步执行的请求(例如,先是1,然后是2,然后是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. 在不执行"同步"的情况下处理所有异步请求(2可能比1更快完成)

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

使用异步库

还有其他异步库,async是最流行的,它们提供了表达所需内容的机制.

Edit

问题的主体已经过编辑,删除了之前同步的示例代码,因此我更新了我的答案以澄清问题.

array.forEachsynchronousres.write也是,所以你可以简单地把你的回调放在你对foreach的调用之后:

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

  res.end();

Javascript相关问答推荐

如何在非独立组件中使用独立组件?

foreach循环中的Typescript字符串索引

如何分配类型脚本中具有不同/额外参数的函数类型

fs. writeFile()vs fs.writeFile()vs fs.appendFile()

Bootstrap动态选项卡在切换选项卡后保持活动状态,导致元素堆叠

如何在Angular中插入动态组件

docx.js:如何在客户端使用文档修补程序

按下同意按钮与 puppeteer 师

我应该绑定不影响状态的函数吗?'

分层树视图

如何从Intl.DateTimeFormat中仅获取时区名称?

在react JS中映射数组对象的嵌套数据

XSLT处理器未运行

WP Bootstrap NavWaker:下拉菜单一次打开所有下拉菜单

NG/Express API路由处理程序停止工作

我想将Sitecore搜索面过滤器从多个转换为单个

Google脚本数组映射函数横向输出

无法读取未定义的属性(正在读取合并)-react RTK

JavaScript:如果字符串不是A或B,则

无法设置RazorPay订阅API项目价格