await不能直接在普通for循环中并发执行异步操作,默认串行;可选串行(for+await)、并行(Promise.all)或可控并发(并发池),需配合try/catch或Promise.allSettled处理错误。

await 不能直接用在普通 for 循环里“并发执行”多个异步操作——它默认是串行等待,但你可以根据需求选择串行、并行或控制并发数。
串行执行(一个接一个)
这是最直观也最安全的方式:每次 await 等待前一个 Promise 完成后再发起下一个请求。适合有依赖关系、或需要严格顺序的场景。
- 用
for...of或传统for循环 +await - 避免在
forEach中直接 await —— 它不会等待,相当于丢弃 Promise
✅ 正确写法:
for (const url of urls) {
const res = await fetch(url);
const data = await res.json();
console.log(data);
}
并行执行(同时发起所有请求)
想让所有异步操作“一起开始”,再统一等待结果,就该用 Promise.all(),而不是在循环里 await。
立即学习“Java免费学习笔记(深入)”;
- 先用
map创建 Promise 数组,再用await Promise.all(...) - 注意:只要其中一个失败,
Promise.all就会整体 reject
✅ 正确写法:
const promises = urls.map(async url => {
const res = await fetch(url);
return res.json();
});
const results = await Promise.all(promises);
可控并发(限制同时请求数)
既不想串行太慢,又怕并行太多压垮服务或触发限流,可用“并发池”方式。
- 维护一个运行中的 Promise 队列,数量不超过阈值(如 3)
- 每完成一个,就补入下一个任务,直到全部提交
✅ 简单实现(不依赖第三方库):
async function runInParallel(tasks, limit = 3) {
const results = [];
const executing = [];
for (const task of tasks) {
const p = task().then(res => {
results.push(res);
return res;
});
executing.push(p);
if (executing.length >= limit) {
await Promise.race(executing);
executing.splice(executing.indexOf(p), 1);
}
}
await Promise.all(executing);
return results;
}
// 使用
await runInParallel(urls.map(u => () => fetch(u).then(r => r.json())), 3);
错误处理别漏掉
无论哪种模式,都要考虑失败情况:
- 串行中:用 try/catch 包裹单次 await,否则一个失败整个流程中断
- 并行中:用
Promise.allSettled()替代Promise.all(),能拿到每个结果的状态 - 并发池中:在每个 task 内部或统一 catch,按需记录或重试
✅ 示例(并行容错):
const results = await Promise.allSettled( urls.map(u => fetch(u).then(r => r.json())) ); const fulfilled = results.filter(r => r.status === 'fulfilled').map(r => r.value);


















