PromisePool模式通过限制并发数控制Promise执行,维护队列与计数器,任务完成即触发下一个;示例实现含add、next、drain方法,支持动态并发限制。

用 PromisePool(承诺池)模式可以动态控制同时执行的 Promise 数量,避免请求打爆服务端或耗尽浏览器资源。
核心思路:维护运行中任务队列
不一次性发起所有请求,而是维持一个“最多 N 个正在执行”的状态。新任务进来时,若当前运行数小于限制,立即执行;否则排队等待。任一任务完成,就从队列取下一个执行。
关键点:
- 用数组模拟任务队列(待执行的 Promise 工厂函数)
- 用计数器跟踪当前并发数
- 每个 Promise 完成后递归触发下一个,形成“链式释放”
简易实现一个可配置的 PromisePool
下面是一个轻量、无依赖的实现,支持动态设置最大并发数:
立即学习“Java免费学习笔记(深入)”;
class PromisePool {
constructor(max = 3) {
this.max = max;
this.running = 0;
this.queue = [];
}
add(promiseFactory) {
this.queue.push(promiseFactory);
this.next();
}
next() {
if (this.running >= this.max || this.queue.length === 0) return;
this.running++;
const factory = this.queue.shift();
Promise.resolve(factory()).finally(() => {
this.running--;
this.next(); // 触发下一轮
});
}
async drain() {
while (this.queue.length > 0 || this.running > 0) {
await new Promise(r => setTimeout(r, 0));
}
}
}
使用示例:
const pool = new PromisePool(2);
// 模拟 5 个异步请求
[1, 2, 3, 4, 5].forEach(i => {
pool.add(() => fetch(`/api/item/${i}`).then(r => r.json()));
});
await pool.drain(); // 等全部完成
更实用的增强版:返回结果 + 支持取消 + 错误聚合
生产环境建议用成熟库如 p-limit 或 es6-promise-pool,但若需定制,可在基础版上扩展:
- 收集每个 Promise 的 resolve 值或 reject 原因
- 为每个任务附加 signal(配合 AbortController)实现取消
- 提供 .then() / .catch() 风格的链式调用接口
- 允许运行时调整 max(需谨慎:只影响后续入队任务)
常见误区提醒
注意别踩这些坑:
- 直接对 Promise 数组用
Promise.all()会全量并发,毫无节制 - 用
setTimeout或for + await是串行,不是并发控制 - 没清空队列或没处理异常,会导致任务“丢失”或卡死
- 在循环里反复创建新 pool 实例,无法共享并发状态


















