异步任务在遍历中的并发执行和串行执行
异步任务在遍历中的并发执行和串行执行
首先解释下什么叫并行和串行
串行:是指在执行多个任务时,各个任务按顺序执行,完成一个才能执行下一个
并行:是指多个任务可以在同一时间间隔内执行(不是同一时刻)
四大遍历(forEach
、for
、for...in
、for...of
)
先下结论,异步任务在 forEach
中是并发执行,而在 for
、for...in
、for...of
中是串行执行
证明结论
首先定义一个 sleep 函数用于遍历
1 | const sleep = async (delay) => { |
对于 forEach
1 | // forEach |
在这个例子中,通过 forEach 遍历执行异步任务 sleep,代码执行的结果是,一秒后,一次性输出以下内容。
可以看出这显然是并发执行的结果
1 | // 同时输出 |
对于 for 循环
1 | // for of |
在这个例子中,通过 for 遍历执行异步任务 sleep,代码执行的结果是,每间隔一秒,依次输出 1,2,3
可以看出这显然是串行执行的结果
1 | // 间隔一秒 |
对于 for…of 和 for…in
输出结果和 for 循环一样,即一个完成后执行下一个
原因分析
为什么 forEach
在执行异步任务的遍历时是 并发执行,和其他三个循环不一样呢?
我们来看下 forEach
的实现
参考 MDN 上 forEach
的 polyfill
:MDN-Array.prototype.forEach(),简单来说,
1 | Array.prototype.forEach = function (callback) { |
相当于 for
循环执行了这个异步函数,所以是并行执行,导致了一次性全部输出结果: