JS 中的循环与异步
JS 中有多种方式实现循环:for; for in; for of; while; do while; forEach; map 等等。假如循环里面的内容是异步并且 await 的,那异步代码究竟是像 Promise.all一样将循环中的代码一起执行,还是每次等待上一次循环执行完毕再执行呢?
首先看结论
forEach 和 map, some, every 循环是并行执行的,相当于 Promise.all,其它 for, for in, for of, while, do while 都是串行执行的。
先定义异步函数 foo 和可遍历数组 arr:
1 | const arr = Array.from({ length: 5 }, (v, k) => k) |
并行执行:
1 | /** |
串行执行:
1 | /** |
如何让 forEach 或者 map 也能串行执行
首先查看 forEach 的 polyfill,简化后可以理解为以下代码:
1 | Array.prototype.forEach = function(callback, thisArg) { |
可以看到本质上 forEach 还是通过 while 循环来实现的,假如我们想要一个异步的 forEach 的话,只需要将 callback 的调用改成 await 即可:
1 | Array.prototype.forEachAsync = async function(callback, thisArg) { |
npm 上有一个更为完备的解决方案:forEachAsync
1 | const forEachAsync = require('forEachAsync').forEachAsync |
就这么多。