一次性发 100 个请求会把浏览器连接数打满、把后端打挂。正确做法是限制并发。
async function pLimit(tasks, limit = 5) {
const results = [];
let idx = 0;
const workers = Array.from({ length: Math.min(limit, tasks.length) }, async () => {
while (idx < tasks.length) {
const i = idx++;
try {
results[i] = await tasks[i]();
} catch (e) {
results[i] = { error: e };
}
}
});
await Promise.all(workers);
return results;
}
要点:
- 结果按下标回填,所以顺序和输入一致,即使完成顺序不同
- 单个失败不能中断整体,所以要 try/catch 包住
idx++是同步操作,不会竞争(JS 单线程)
最常见的错误写法
await Promise.all(urls.map(fetch)); // 瞬间全发,等于没限流
Promise.all 只负责「等全部完成」,不负责控制并发数。
失败要不要中断?
批量导入这类场景用 Promise.allSettled 收集全部结果;
强一致流程(比如多步提交)才用 Promise.all 快速失败。
楼主 · 2026-09-28 14:31 · 浏览 3

