Node.js中forEach结合Promise实现指定顺序打印的问题
问题分析与解决方案
你的问题出在**forEach会同步遍历数组所有元素**,再加上print函数里的console.log是在Promise的executor中执行的(这部分属于同步代码),所以会先一口气把1、2、3、4全部打印出来,之后各个then回调里的addAndPrint才依次执行,最终导致顺序不符合预期。
要实现串行的顺序执行(先打印elem,再打印elem+100,再处理下一个elem),可以用以下两种方法:
方法1:使用async/await + for...of循环
这是最直观易读的方式,利用await等待每个Promise完成后再进行下一次循环:
var arr = [1, 2, 3, 4]; async function processArr() { for (const elem of arr) { await print(elem); // 等待当前print完成,再执行addAndPrint addAndPrint(elem); } } function print(elem){ return new Promise(function(resolve, reject){ console.log(elem); resolve(elem); }); } function addAndPrint(elem){ console.log(elem + 100); } processArr(); // 调用执行函数
方法2:使用reduce构建串行Promise链
如果不想用async/await,也可以用数组的reduce方法把所有Promise串联起来,让前一个操作完成后再执行下一个:
var arr = [1, 2, 3, 4]; arr.reduce((prevPromise, elem) => { return prevPromise.then(() => { return print(elem).then(() => addAndPrint(elem)); }); }, Promise.resolve()); // 初始Promise作为执行起点 function print(elem){ return new Promise(function(resolve, reject){ console.log(elem); resolve(elem); }); } function addAndPrint(elem){ console.log(elem + 100); }
生效逻辑说明
- 方法1里的
await会暂停循环,直到当前print的Promise被resolve,之后才会执行addAndPrint,再进入下一次循环处理下一个元素。 - 方法2里的
reduce会把前一个Promise的结果作为下一个then的起点,确保每一步操作都在前一个操作完成后才开始,从而保证了elem和elem+100的打印顺序,以及元素之间的串行处理。
内容的提问来源于stack exchange,提问作者errorMessage
相关产品推荐
相关产品推荐

