如何动态顺序执行数量可变的Promise?
动态顺序执行数量可变的Promise方案
嘿,我明白你遇到的问题了——静态的Promise链式调用只能处理固定数量的任务,一旦任务数量动态变化就抓瞎了对吧?别担心,咱们用数组的reduce方法就能轻松搞定动态顺序执行的需求,下面给你一步步拆解方案:
先回顾静态实现的局限
你之前的静态写法大概是这样的,只能提前写死要执行的Promise数量:
function waitFor(timeout) { return new Promise(function(resolve, reject) { setTimeout(function() { resolve(`Finished waiting ${timeout} milliseconds`); }, timeout); }); } // 静态顺序执行:数量固定,新增任务就得手动加then链 waitFor(1000) .then(result => { console.log(result); return waitFor(2000); }) .then(result => { console.log(result); return waitFor(3000); }) .catch(err => console.error(err));
这种写法在任务数量不确定时完全没法用,比如从接口动态获取要执行的任务列表,这时候就得用动态构建Promise链的方式。
动态顺序执行的核心实现
我们可以利用数组的reduce方法,把动态数量的Promise任务依次串成一条执行链。关键是要传Promise工厂函数数组,而不是直接传Promise数组——因为直接传Promise的话它们会立即并行执行,咱们要的是顺序执行,所以得在上一个任务完成后再创建并执行下一个Promise。
// 通用的动态顺序执行函数 function sequentialPromises(promiseFactoryArray) { // 用reduce构建链式Promise,初始值是一个已resolved的Promise作为起点 return promiseFactoryArray.reduce((prevPromise, currentFactory) => { return prevPromise.then(prevResult => { // 可选:打印上一个任务的结果(如果需要的话) if (prevResult !== undefined) { console.log(prevResult); } // 执行当前的Promise工厂,返回新的Promise return currentFactory(); }); }, Promise.resolve()); } // 使用示例:动态任务列表,数量随便改 const dynamicTimeouts = [1000, 2000, 500, 3000]; // 比如从接口拿到的任务参数 // 把每个参数转换成返回Promise的工厂函数 const promiseFactories = dynamicTimeouts.map(timeout => () => waitFor(timeout)); // 启动顺序执行 sequentialPromises(promiseFactories) .then(finalResult => { console.log("所有任务执行完成,最终结果:", finalResult); }) .catch(err => { console.error("执行过程出错:", err); });
进阶优化:支持结果回调与参数传递
如果需要在每个任务完成时做自定义处理,或者把上一个任务的结果传给下一个任务,可以稍微改造一下函数:
function sequentialPromises(promiseFactoryArray, onStepComplete) { return promiseFactoryArray.reduce((prevPromise, currentFactory) => { return prevPromise.then(prevResult => { // 每个任务完成时触发自定义回调 if (prevResult !== undefined && onStepComplete) { onStepComplete(prevResult); } // 把上一个任务的结果传给当前的Promise工厂 return currentFactory(prevResult); }); }, Promise.resolve()); } // 优化版使用示例 sequentialPromises(promiseFactories, result => { console.log("当前任务完成:", result); }) .then(finalResult => { console.log("所有任务执行完毕,最终结果:", finalResult); }) .catch(err => console.error("执行出错:", err));
这样不管你的任务数量是3个还是10个,只要把它们放进数组里,就能自动按顺序挨个执行,完美解决动态数量的问题~
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

