推荐用 promise.allsettled() 并行执行多个 await 请求并各自容错,它返回每个请求的完整状态(fulfilled/rejected),不因单个失败中断,适合需明确知晓各请求成败的场景。

直接用 try...catch 包裹多个 await 是串行的,而且一旦出错就中断后续;要并行执行、各自容错,关键在于不让错误互相干扰——核心思路是:让每个请求的 Promise 自己消化错误,或用更合适的聚合 API。
用 Promise.allSettled() 获取全部结果(含失败)
这是最推荐的方式,尤其适合“必须知道每个请求成败”的场景。它不会因某个失败而中断,返回每个 Promise 的完整状态(fulfilled 或 rejected)。
- 所有请求真正并发发起,不等待彼此
- 返回数组,每个元素带
status、value(成功时)或reason(失败时) - 无需额外 try/catch,错误已结构化封装
示例:
async function fetchAllData() {
const results = await Promise.allSettled([
fetch('/api/user').then(r => r.json()),
fetch('/api/orders').then(r => r.json()),
fetch('/api/profile').then(r => r.json())
]);
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`请求 ${index + 1} 成功:`, result.value);
} else {
console.warn(`请求 ${index + 1} 失败:`, result.reason);
}
});
return results;
}
为每个 Promise 单独加 .catch() 防止传播
如果仍想用 Promise.all()(比如只关心全部成功),但又不想让它被单个失败拖垮,可提前在每个 Promise 上拦截错误,转成正常值(如 null 或默认对象)。
- 每个请求独立兜底,错误不会上抛到
Promise.all() - 返回的数组里,失败项变成你指定的 fallback 值
- 适合“有数据就用,没数据也不报错”的宽松逻辑
示例:
async function fetchWithFallback() {
const [user, orders, profile] = await Promise.all([
fetch('/api/user').then(r => r.json()).catch(() => null),
fetch('/api/orders').then(r => r.json()).catch(() => []),
fetch('/api/profile').then(r => r.json()).catch(() => ({}))
]);
return { user, orders, profile };
}
手动并发 + 独立 try/catch(适合需精细控制)
当需要对每个请求做差异化错误处理(比如重试、上报、降级策略不同),可先创建所有 Promise,再逐个 await 并各自包裹 try/catch。
- 保持并发发起(Promise 构造阶段无 await)
- 每个 await 后能单独写日志、调重试、返回定制 fallback
- 代码稍长,但控制粒度最细
示例:
async function fetchWithPerRequestLogic() {
const userP = fetch('/api/user');
const ordersP = fetch('/api/orders');
const profileP = fetch('/api/profile');
let user = null;
try {
const res = await userP;
user = await res.json();
} catch (err) {
console.error('用户请求失败,启用本地缓存');
user = getCachedUser();
}
let orders = [];
try {
const res = await ordersP;
orders = await res.json();
} catch (err) {
console.error('订单请求失败,返回空列表');
}
let profile = {};
try {
const res = await profileP;
profile = await res.json();
} catch (err) {
console.error('资料请求失败,使用默认头像');
profile.avatar = '/default-avatar.png';
}
return { user, orders, profile };
}
避免常见坑:别混用串行和并行逻辑
容易误写的两种情况:
-
错误写法:把
await fetch(...)写在数组里 —— 这其实是串行,不是并发 -
错误写法:直接
await promise后又试图读promise.data—— Promise 对象本身没有 data 属性,必须 await 后才能拿到解析值 -
注意点:
Promise.allSettled是现代标准(ES2020+),旧环境需 polyfill;若需兼容性,可用Promise.all().catch()+ 手动兜底替代
本质上,并行 + 独立错误处理不是语法限制,而是对 Promise 生命周期的理解问题:只要 Promise 创建时不 await,它们就自然并发;错误是否传播,取决于你有没有在链上用 .catch() 或 try/catch 拦截。











