Async/await解析JSON:重构异步forEach为map时遇执行顺序问题求助
如何重构出能顺序执行的asyncForEach函数?
嘿,我懂你的困扰——你想用数组的map/forEach重构原来的asyncForEach,但试了map之后发现没法像原for循环那样逐个等待异步回调执行,反而所有操作一下子就并行跑起来了对吧?
先说说为什么你用map的写法行不通:array.map()会立刻遍历整个数组,给每个元素创建一个异步函数,然后返回一个Promise数组。但你直接await这个数组的话,JavaScript并不会逐个等待这些Promise完成——因为await只对单个Promise生效,面对数组它会直接把数组当作普通值resolve掉,所以所有异步回调其实是并行执行的,完全没实现顺序等待的效果。
如果想用数组方法复刻原for循环的顺序执行逻辑,最靠谱的方案是用Array.prototype.reduce,它能帮我们把异步操作串联起来:
async function asyncForEach(array, callback) { await array.reduce(async (prevPromise, item, index) => { // 先等待前一个元素的回调执行完毕 await prevPromise; // 再执行当前元素的回调 await callback(item, index, array); }, Promise.resolve()); // 初始化一个已完成的Promise,让第一个回调能正常启动 }
这个写法的核心逻辑是:reduce每次迭代时,都会等待前一次迭代返回的Promise完成,再执行当前的回调。这样就完美复刻了原for循环里await callback(...)的顺序等待行为,每个回调都会等上一个执行完毕才开始。
至于forEach,其实也没法直接实现顺序等待——因为forEach是同步遍历的,它会一次性把所有异步回调都调用起来,根本不会等待每个回调的Promise完成,同样会导致并行执行,达不到你的需求。
内容的提问来源于stack exchange,提问作者dobbey
相关产品推荐
相关产品推荐

