如何让Promise.map顺序执行Promise函数(禁用async/await)
实现Promise函数在数组遍历中的顺序执行(无需async/await)
我完全懂你的痛点——现在用Promise.map会一下子把5个t2实例全部触发,它们的操作是并行跑的,但你需要严格按顺序来,前一个t2的所有异步操作都完成后,再启动下一个,而且还不能用async/await。那咱们用原生Promise的链式调用就能搞定这个问题。
问题根源
Promise.map(不管是Bluebird实现还是其他类库的)的设计就是并行处理数组元素,所以它会同时发起所有t2的调用,这就是你看到“五个实例先全部触发,再依次进入逻辑”的原因。要改成串行,我们需要把数组元素逐个加到Promise链里,让每个步骤都依赖前一步的完成。
修改后的代码
直接修改t1函数,用数组的reduce方法来构建串行的Promise链:
function t1(){ let arr1 = [1,2,3,4,5]; // 用reduce累积Promise链,实现顺序执行 return arr1.reduce((currentChain, val) => { return currentChain.then(() => { const params = { "param1" : val }; return t2(params); }); }, Promise.resolve()); // 初始化为一个已完成的Promise,作为链的起点 } function t2(event){ return Promise.resolve() .then(() =>{ // 这里的操作现在会严格按数组顺序执行:前一个t2的这步完成后,下一个才会进来 }) .then(() =>{ // 后续的链式操作也会跟着串行执行 }) }
工作原理
reduce的初始值是Promise.resolve(),一个已经处于resolved状态的Promise,作为整个链的起点。- 第一次迭代时,我们在这个初始Promise的
then里调用第一个t2,它会返回一个新的Promise。 - 第二次迭代时,我们把这个新的Promise作为
currentChain,在它的then里调用第二个t2,以此类推。 - 这样每一个
t2的调用都必须等前一个t2的所有异步操作(包括它的整个Promise链)全部完成后才会触发,完美实现你要的同步执行效果。
这个方案完全基于原生Promise API,不需要额外依赖,也避开了async/await的限制,刚好符合你的需求。
内容的提问来源于stack exchange,提问作者user3807691
相关产品推荐
相关产品推荐

