9

数组遍历

forEach 函数与 map 相似,但是它不返回结果,而是为每个元素运行该函数并丢弃结果。 实际上,重要的部分是调用函数的副作用

例如,将每个元素同步打印到控制台

const arr = [1, 2, 3];

arr.forEach((i) => {
    console.log(i);
});

// 1
// 2
// 3

console.log("完成同步");
// 完成同步

由于结果并不重要,因此可以使用异步函数作为迭代器:

const arr = [1, 2, 3];

arr.forEach(async (i) => {
    // 每个元素需要花费不同的时间才能完成
    await sleep(10 - i);
    console.log(i);
});

console.log("完成异步");
// 完成异步

// 3
// 2
// 1

How to use async functions with Array.forEach in Javascript

控制时间-等待完成

但是,并不奇怪,该函数被异步调用,并且程序没有按时间顺序完成。 这是与同步版本的重要区别,因为在执行下一行时,同步forEach已完成,而异步版本尚未完成。 因此,“完成异步”日志显示在元素之前。

要在继续进行之前等待所有函数调用完成,请使用带有 Promise.allmap 并不要返回值:

const arr = [1, 2, 3];

await Promise.all(arr.map(async (i) => {
    await sleep(10 - i);
    console.log(i);
}));

// 3
// 2
// 1

console.log("完成异步");
// 完成异步

How to use async functions with Array.forEach in Javascript222.png

进行此更改后,“完成异步”排在最后。

控制顺序-逐步完成

但是请注意,迭代函数是并行调用的。
若要忠实地遵循同步遍历,可以在reduceawait累加器,即如下的await memo

const arr = [1, 2, 3];

await arr.reduce(async (memo, i) => {
    await memo;
    await sleep(10 - i);
    console.log(i);
}, undefined);

// 1
// 2
// 3

console.log("完成异步");
// 完成异步

How to use async functions with Array.forEach in Javascript - Advance23324234.png

这样,元素会依次处理,程序执行将等待整个数组完成后再继续。

结论

异步的数组遍历很容易使用,但是是用 forEachmapreduce 取决于时序要求。

  • 如果你只想在任何时候运行这些功能,请使用 forEach
  • 如果要确保继续操作之前完成操作,请使用 map
  • 如果你需要一个一个地运行它们,请使用 reduce

湖人总冠军
514 声望721 粉丝

菜鸟与孤鹜齐飞