处理多个独立异步并发应避免串行await,优先用Promise.all(全成功才继续)或Promise.allSettled(容忍部分失败),循环中需先map收集Promise再并行执行,必要时用Promise.race实现竞速或超时控制。

处理多个独立的异步并发,核心是避免用 连续 await 造成串行等待,而应主动选择并行执行机制。关键不在于“能不能一起发”,而在于“要不要等全部完成”以及“能否容忍个别失败”。
用 Promise.all 并行发起,全部成功才继续
当所有请求互不依赖、且业务逻辑要求全部成功才有意义(比如首页三块数据缺一不可),就用 Promise.all:
- 所有异步操作同时启动,总耗时 ≈ 最慢那个任务
- 只要有一个 rejected,整个
Promise.all立即 reject,不会等其余完成 - 适合强一致性场景,错误可统一在 try/catch 中捕获
示例:
async function loadHomeData() {
try {
const [user, posts, tags] = await Promise.all([
fetch('/api/user').then(r => r.json()),
fetch('/api/posts').then(r => r.json()),
fetch('/api/tags').then(r => r.json())
]);
return { user, posts, tags };
} catch (err) {
console.error('加载首页数据失败', err);
}
}
用 Promise.allSettled 容忍部分失败
当某些请求失败不影响整体流程(比如用户信息必须加载,但推荐内容加载失败可降级为空),就用 Promise.allSettled:
立即学习“Java免费学习笔记(深入)”;
- 所有 Promise 都会执行到底,不管成功或失败
- 返回数组,每项含
status: 'fulfilled' | 'rejected'和对应value或reason - 需要手动判断状态再取值,灵活性高
示例:
async function loadWithFallback() {
const results = await Promise.allSettled([
fetch('/api/user').then(r => r.json()),
fetch('/api/recommend').then(r => r.json()),
fetch('/api/ads').then(r => r.json())
]);
const user = results[0].status === 'fulfilled' ? results[0].value : null;
const recommend = results[1].status === 'fulfilled' ? results[1].value : [];
const ads = results[2].status === 'fulfilled' ? results[2].value : [];
return { user, recommend, ads };
}
别在循环里盲目 await
遍历数组发起多个请求时,常见误区是直接 for...of + await —— 这本质是串行:
- ❌
for (const id of ids) { await fetch(`/api/item/${id}`); }→ 一个接一个,耗时累加 - ✅ 收集所有 Promise 后再
await Promise.all(...)→ 并行发出
正确写法:
async function loadItems(ids) {
const promises = ids.map(id => fetch(`/api/item/${id}`).then(r => r.json()));
return await Promise.all(promises);
}
按需竞速或超时控制
有些场景不需要等全部,而是“谁快用谁”或“超时就放弃”:
-
Promise.race([p1, p2, timeout]):返回最先 settled 的结果,适合兜底接口或 A/B 测试 - 搭配自定义 timeout Promise,可防止某个请求长期卡住主线程逻辑
例如:
const timeout = new Promise((_, reject) =>
setTimeout(() => reject(new Error('请求超时')), 3000)
);
const result = await Promise.race([
fetch('/api/main').then(r => r.json()),
timeout
]);


















