Promise实现的并发调度器核心是控制同时执行任务数不超过阈值,通过维护running计数器、任务队列和limit上限,add方法接收Promise工厂函数并返回其结果,runNext按需启动任务,完成时自动调度下一个。

用 Promise 实现一个支持并发上限的请求调度器,核心是控制同时执行的 Promise 数量不超过设定阈值,其余任务排队等待。关键不在于“发请求”,而在于“调度”——把异步任务组织成可控的并发流。
调度器的基本结构
调度器需要维护:当前运行中的任务数、待执行的任务队列、最大并发数(limit)。每次有新任务加入时,如果当前运行数
- 每个任务包装为返回 Promise 的函数(如 () => fetch(url)),便于统一调度
- 用一个计数器 running 跟踪当前并发数,避免用 setInterval 或轮询
- 任务完成时递减计数器,并尝试从队列中取出下一个执行
实现一个 add 方法来提交任务
add() 是调度器对外的唯一入口,它接收一个 Promise 工厂函数(不是直接传 Promise,否则无法控制何时开始),返回该任务的 Promise 结果,方便调用方 await 或链式处理。
- 内部将工厂函数推入队列
- 立即调用 runNext() 尝试启动任务:若 running ,则取出队首、执行、计数+1
- 任务 resolve/reject 后,计数−1,并再次调用 runNext() 继续调度
完整可运行代码示例
下面是一个轻量、无依赖的实现:
立即学习“Java免费学习笔记(深入)”;
class Scheduler {
constructor(limit) {
this.limit = limit;
this.queue = [];
this.running = 0;
}
add(promiseCreator) {
return new Promise((resolve, reject) => {
this.queue.push({ promiseCreator, resolve, reject });
this.runNext();
});
}
runNext() {
if (this.queue.length === 0 || this.running >= this.limit) return;
this.running++;
const { promiseCreator, resolve, reject } = this.queue.shift();
promiseCreator()
.then(resolve)
.catch(reject)
.finally(() => {
this.running--;
this.runNext();
});
}
}
// 使用示例:
const scheduler = new Scheduler(2);
const urls = ['/api/1', '/api/2', '/api/3', '/api/4'];
const promises = urls.map(url =>
scheduler.add(() => fetch(url).then(res => res.json()))
);
Promise.all(promises).then(results => console.log(results));
注意:这里 promiseCreator 是函数,确保每次执行都是全新 Promise,避免提前触发或状态复用问题。
进阶考虑:取消、优先级、错误隔离
基础版已满足大多数场景。如需增强:
- 取消支持:可在 add() 返回的 Promise 上挂 cancel() 方法,配合 AbortController
- 优先级队列:把队列换成最小堆,按优先级排序,而非先进先出
- 错误不中断后续:把 .catch(reject) 改为 .catch(err => { resolve({ error: err }) }),让失败任务也释放 slot


















