控制同时进行的请求数量代码实现
js
async function runWithConcurrency(tasks, maxConcurrent) {
const results = []; // 存放所有任务的最终结果(Promise)
const activeTasks = []; // 当前正在执行的任务对应的Promise(用于跟踪)
for (const task of tasks) {
// 1. 创建代表当前任务的Promise。`() => task()` 确保任务在需要时才启动
const taskPromise = Promise.resolve().then(task);
results.push(taskPromise); // 保存结果,最后统一用 Promise.all 等
// 2. 创建任务完成后的清理操作:从 activeTasks 中移除自己
const removeFromActive = () => activeTasks.splice(activeTasks.indexOf(removeFromActive), 1);
activeTasks.push(removeFromActive); // 注意:这里存的是清理函数对应的Promise
// 3. 如果当前活跃任务数已达上限,就等任意一个完成
if (activeTasks.length >= maxConcurrent) {
await Promise.race(activeTasks); // 等 activeTasks 数组里任意一个Promise完成
}
// 4. 将清理操作与实际任务完成挂钩
taskPromise.then(removeFromActive, removeFromActive); // 无论成功失败都清理
}
// 5. 等待所有任务完成(无论是否在活跃池中)
return Promise.allSettled(results); // 或者用 Promise.all(results) 只关心成功
}
// 使用示例
const userIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const tasks = userIds.map(id =>() => (id));
// 最多同时发出 3 个请求
runWithConcurrency(tasks, 3).then(results => {
console.log('所有用户获取完成 (并发控制):', results);
});
- 这个函数会确保最多只有maxConcurrent个请求同时在进行。
- 当一个请求完成,池子里有空位了,才会开始下一个请求。