forEach
函数与 map
类似,可是它不返回结果,而是为每一个元素运行该函数并丢弃结果。 实际上,重要的部分是调用函数的反作用。数组
例如,将每一个元素同步打印到控制台异步
const arr = [1, 2, 3]; arr.forEach((i) => { console.log(i); }); // 1 // 2 // 3 console.log("完成同步"); // 完成同步
因为结果并不重要,所以可使用异步函数做为迭代器:async
const arr = [1, 2, 3]; arr.forEach(async (i) => { // 每一个元素须要花费不一样的时间才能完成 await sleep(10 - i); console.log(i); }); console.log("完成异步"); // 完成异步 // 3 // 2 // 1
可是,并不奇怪,该函数被异步调用,而且程序没有按时间顺序完成。 这是与同步版本的重要区别,由于在执行下一行时,同步forEach已完成,而异步版本还没有完成。 所以,“完成异步”日志显示在元素以前。函数
要在继续进行以前等待全部函数调用完成,请使用带有 Promise.all
的 map
并不要返回值:spa
const arr = [1, 2, 3]; await Promise.all(arr.map(async (i) => { await sleep(10 - i); console.log(i); })); // 3 // 2 // 1 console.log("完成异步"); // 完成异步
进行此更改后,“完成异步”排在最后。日志
可是请注意,迭代函数是并行调用的。
若要忠实地遵循同步遍历,能够在reduce
中await
累加器,即以下的await memo
:code
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("完成异步"); // 完成异步
这样,元素会依次处理,程序执行将等待整个数组完成后再继续。blog
异步的数组遍历很容易使用,可是是用 forEach
,map
或 reduce
取决于时序要求。ip
forEach
。map
。reduce
。