首页
Preview

JavaScript:使用forEach()和async/await

async/await非常棒,但有一个地方很棘手:forEach()

让我们试一下:

const waitFor = (ms) => new Promise(r => setTimeout(r, ms));[1, 2, 3].forEach(async (num) => {
  await waitFor(50);
  console.log(num);
});console.log('Done');

如果你使用 node.js(≥ 7.6.0)运行此代码,会发生以下情况:

$ node forEach.js
$ Done

怎么回事?

console.log(num) 没有显示在控制台中。

让我们重新创建 forEach() 以理解发生了什么:

Array.prototype.forEach = function (callback) {
  // this represents our array
  for (let index = 0; index < this.length; index++) {
    // We call the callback for each entry
    callback(this[index], index, this);
  }
};

<em>forEach()</em> 的真正 polyfill 可在 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Polyfill 中找到。

正如你所看到的,callback 被调用了,但在进入数组的下一个条目之前,我们没有等待它完成

我们可以通过创建自己的 asyncForEach() 方法来解决这个问题:

async function asyncForEach(array, callback) {
  for (let index = 0; index < array.length; index++) {
    await callback(array[index], index, array);
  }
}

然后,我们可以更新我们的示例来使用我们的 asyncForEach 方法:

asyncForEach([1, 2, 3], async (num) => {
  await waitFor(50);
  console.log(num);
})console.log('Done');

通过在 node 中运行此代码,我们现在可以看到:

$ node forEach.js
$ Done
$ 1
$ 2
$ 3

我们离成功更近了!

实际上,我们的 asyncForEach 返回一个 Promise(因为它被包装在一个 async 函数中),但我们在记录 'Done' 之前没有等待它完成。

让我们再次更新我们的示例,将执行包装在一个 async 方法中:

const start = async () => {
  await asyncForEach([1, 2, 3], async (num) => {
    await waitFor(50);
    console.log(num);
  });
  console.log('Done');
}start();

让我们最后运行一次:

$ node forEach.js
$ 1
$ 2
$ 3
$ Done

🎉 现在我们有一种使用 forEachasync/await 的方法了 🎉

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
jacob
暂无描述

评论(0)

添加评论