function limitPromise(promiseFnList, start = 0, limit = 5) {
const result = []; // 存储所有的 Promise 任务
const executing = new Set(); // 正在执行的 Promise 对象
let i = start;
const queue = () => {
// 边界条件:如果 promises 长度为 0,或 i 到达末尾,就返回一个空的 promise
if (i >= promiseFnList.length) return Promise.resolve();
// 拿到一个 promise并运行,设置运行完成后从 executing 集合中删除
const p = promiseFnList[i++]().finally(() => executing.delete(p));
// 将运行中的 promise 添加到 executing 集合
executing.add(p);
// 并同时添加到 result 数组
result.push(p);
// 使用 Promise.race,每当 executing 数组中 promise 数量低于 limit,就实例化新的 promise 并执行
// const r = executing.size >= limit ? Promise.race(executing) : Promise.resolve();
// 递归,直到遍历完 promises
// return r.then(() => queue());
// 或者一步到位
return executing.size >= limit ? Promise.race(executing).then(() => queue()) : queue();
// 最后,用 Promise.all 将 result 中的结果输出,其会等待最后一批执行中的 promise 状态变为完成后才能进入 then 方法
return queue().then(() => Promise.all(result));
function fakePromise(url, time, success = true) {
return function() {
return new Promise((resolve, reject) => {
console.log('开始' + url);
setTimeout(() => {
if (success) resolve(`收到来自${url}的相应!`);
else reject(`${url}失败!`);
}, time * 1000);
const promiseFnList = [
fakePromise('1', 1, false),
fakePromise('2', 3),
fakePromise('3', 2),
fakePromise('4', 1),
fakePromise('5', 1),
fakePromise('6', 4),
fakePromise('7', 4),
fakePromise('8', 3),
fakePromise('9', 3),
fakePromise('10', 1),
// 从下标为 3 的项开始,最大并发数为 2
limitPromise(promiseFnList, 3, 2).then(res => console.log(res), err => console.log(err));
版权