返回

async与forEach引发的争议,ES6中的黑科技?

前端

在ES6中,async和await是两个非常重要的关键词,它们可以让我们以同步的方式编写异步代码。这使得我们的代码更加清晰和易于阅读。但是,当我们使用async和await时,也需要注意一些陷阱。

最近,我看到一篇文章,题目是“async在forEach中不生效”。这篇文章引起了很大的争议。有些人认为async在forEach中确实不生效,而另一些人则认为async在forEach中是可以生效的。

那么,async在forEach中到底能不能生效呢?

答案是:可以生效,但是有条件。

async在forEach中生效的条件是:forEach中的回调函数必须是一个异步函数。

也就是说,如果forEach中的回调函数是一个同步函数,那么async在forEach中就不会生效。

为了证明这一点,我们可以做一个小实验。

首先,我们定义一个同步函数:

function syncFunction() {
  console.log('This is a sync function.');
}

然后,我们定义一个异步函数:

async function asyncFunction() {
  await new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, 1000);
  });

  console.log('This is an async function.');
}

接下来,我们使用forEach来遍历一个数组:

const array = [1, 2, 3];

array.forEach(syncFunction);
array.forEach(asyncFunction);

当我们运行这段代码时,我们会看到以下输出:

This is a sync function.
This is a sync function.
This is a sync function.
This is an async function.

从这个输出中,我们可以看到,syncFunction在forEach中被调用了三次,而asyncFunction只被调用了一次。这说明,async在forEach中确实可以生效,但是只有当forEach中的回调函数是一个异步函数时。

那么,为什么有些人会认为async在forEach中不生效呢?

这可能是因为他们没有意识到forEach中的回调函数必须是一个异步函数。他们可能尝试在forEach中使用一个同步函数,结果发现async没有生效,于是就认为async在forEach中不生效。

现在,我们已经知道了async在forEach中可以生效的条件。那么,我们应该如何在forEach中正确使用async和await呢?

首先,我们需要确保forEach中的回调函数是一个异步函数。

其次,我们需要在回调函数中使用await来等待异步任务完成。

例如,我们可以这样使用async和await来在forEach中并行执行异步任务:

const array = [1, 2, 3];

async function fetchItem(item) {
  await new Promise((resolve) => {
    setTimeout(() => {
      resolve(item);
    }, 1000);
  });

  return item;
}

async function main() {
  const results = await Promise.all(array.map(fetchItem));

  console.log(results);
}

main();

当我们运行这段代码时,我们会看到以下输出:

[1, 2, 3]

从这个输出中,我们可以看到,forEach中的异步任务被并行执行了。

这就是如何在forEach中正确使用async和await。