promise本身不直接提供队列控制能力,但可通过链式调用、reduce累积、封装函数实现串行执行,或通过计数器+队列实现并发限制。

Promise 本身不直接提供“队列控制”能力,但可以通过链式调用、串行执行和状态管理,轻松实现异步任务的有序、可控执行——关键在于避免并发竞争,确保一个 Promise 完成后再启动下一个。
用 then 链实现串行异步队列
最基础也最常用的方式:把多个异步操作依次用 .then() 连接,前一个的返回值(尤其是返回新 Promise)会作为后一个的输入,天然形成串行队列。
示例:按顺序加载三张图片
function loadImg(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(src);
img.onerror = () => reject(new Error(`Failed to load ${src}`));
img.src = src;
});
}
<p>// 串行执行:等第一张加载完,再加载第二张,依此类推
loadImg('a.jpg')
.then(() => loadImg('b.jpg'))
.then(() => loadImg('c.jpg'))
.then(() => console.log('All loaded'))
.catch(err => console.error(err));</p>用 reduce 动态构建 Promise 队列
当任务列表不确定或需动态生成时,可用数组 reduce 累积 Promise 链,让每个任务都等待前一个完成后再开始。
- 初始值设为
Promise.resolve(),作为链起点 - 每次
acc.then(() => task()),保证严格串行 - 适合处理数组中的异步操作,如批量 API 请求、文件上传等
const urls = ['api/1', 'api/2', 'api/3'];
<p>urls.reduce((acc, url) => {
return acc.then(() => fetch(url).then(r => r.json()));
}, Promise.resolve())
.then(() => console.log('All requests done'));</p>封装通用串行执行函数(promiseSeries)
把逻辑抽象成可复用函数,接收任务函数数组,返回串行执行的 Promise:
function promiseSeries(tasks) {
return tasks.reduce((acc, task) => {
return acc.then(result => {
// 支持任务返回值(如上一个结果传给下一个)
return task(result);
});
}, Promise.resolve());
}
<p>// 使用示例:带上下文传递的任务
const tasks = [
() => Promise.resolve(10),
(x) => Promise.resolve(x * 2),
(x) => Promise.resolve(<code>Result: ${x}</code>)
];</p><p>promiseSeries(tasks).then(console.log); // "Result: 20"</p>控制并发数(限制同时运行的 Promise 数量)
若需“最多 3 个请求并行”,而非完全串行,可用 Promise.all + 分批调度 或第三方库(如 p-limit),但纯 JS 可手写简易版:
- 维护一个运行中计数器和待执行队列
- 每次有完成就从队列取下一个执行
- 核心是“完成回调触发下一轮”,避免竞态
精简实现(不依赖外部库):
function promisePool(tasks, limit = 3) {
const results = [];
let inProgress = 0;
let nextIndex = 0;
<p>return function run() {
if (nextIndex >= tasks.length && inProgress === 0) {
return Promise.resolve(results);
}</p><pre class="brush:php;toolbar:false;">while (inProgress results.push(res))
.catch(err => results.push(err))
.finally(() => {
inProgress--;
run(); // 尝试调度下一个
});
}
return Promise.resolve().then(run);}(); }
调用:promisePool([() => api1(), () => api2(), ...], 2) 即可限制最多 2 个并发。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











