SOURCE

/**
 * Promise 并发池:控制最大并发数
 * @param {Array<() => Promise>} tasks 任务数组(每项是返回Promise的函数)
 * @param {number} limit 最大并发数
 * @returns {Promise<Array>} 所有任务执行完成的结果数组
 */


async function promisePool(tasks, limit) {
    // 存储所有任务的Promise,最终通过Promise.all返回全部结果
    const result = [];
    // 用Set存储正在执行的任务,方便快速增删和判断数量
    const executing = new Set();

    // 遍历所有任务,逐个处理
    for (const task of tasks) {
        // 包装任务为Promise,确保即使task不是异步函数也能正常执行
        const p = Promise.resolve().then(() => task());
        // 将当前任务的Promise加入结果数组
        result.push(p);
        // 将当前任务加入"正在执行"集合
        executing.add(p);

        // 任务执行完成(成功/失败)后,从"正在执行"集合中移除
        p.finally(() => {
            executing.delete(p);
        });

        // 若正在执行的任务数达到最大并发数,等待任意一个任务完成
        if (executing.size >= limit) {
            await Promise.race(executing);
        }
    }

    // 等待所有任务执行完成,返回结果数组
    return Promise.all(result);
}

// 测试用例
function createTask(time, id) {
    return () => new Promise((resolve) => {
        setTimeout(() => {
            console.log(`任务${id}完成`);
            resolve(id);
        }, time);
    });
}

// 测试:最大并发数2,4个任务
promisePool([
    createTask(1000, 1),
    createTask(500, 2),
    createTask(800, 3),
    createTask(1200, 4)
], 2).then(res => {
    console.log('所有任务结果:', res); // [1,2,3,4]
});
console 命令行工具 X clear

                    
>
console