推荐使用 Promise.allSettled() 并发执行并结构化处理结果,它让所有请求并行发起、返回含 status/value 或 reason 的数组,错误已封装可逐项判断;也可用 .catch() 为每个 Promise 设默认值后配合 Promise.all(),或用 to 封装实现 [error, result] 解构式处理。

在 async 函数里并发处理多个异步任务,核心是避免用多个 await 串行等待,而要让请求真正同时发起;错误处理的关键是不让单个失败中断整体流程,同时能明确知道每个任务的成败状态。
用 Promise.allSettled() 并发执行 + 结构化结果
这是最推荐的方式,尤其适合“所有请求都要发、每个结果都得判断”的场景:
- 所有请求并行发起,互不阻塞
- 返回数组,每项含
status('fulfilled'或'rejected'),以及对应的value或reason - 无需在外层加 try/catch,错误已封装进结果,可逐项处理
示例:
async function loadDashboardData() {
const results = await Promise.allSettled([
fetch('/api/user').then(r => r.json()),
fetch('/api/orders').then(r => r.json()),
fetch('/api/notifications').then(r => r.json())
]);
const data = {};
const errors = [];
results.forEach((res, i) => {
if (res.status === 'fulfilled') {
data[i] = res.value;
} else {
errors.push({ index: i, reason: res.reason });
}
});
if (errors.length > 0) {
console.warn('部分接口加载失败:', errors);
}
return data;
}
为每个 Promise 单独兜底,转成默认值
如果你希望最终拿到的是一个“干净”的数据数组(比如全是对象或空数组),而不是带状态的对象,可以提前用 .catch() 拦截错误:
- 每个请求自己消化错误,返回预设 fallback 值(如
null、[]、{}) - 再配合
Promise.all(),就不会因某一项失败而 reject 整个调用 - 适合对缺失数据容忍度高、不需单独上报错误的场景
示例:
async function loadWithDefaults() {
const [user, posts, settings] = await Promise.all([
fetch('/api/user').then(r => r.json()).catch(() => ({})),
fetch('/api/posts').then(r => r.json()).catch(() => []),
fetch('/api/settings').then(r => r.json()).catch(() => ({}))
]);
return { user, posts, settings };
}
统一包装成结构化结果(error/result)
把每个异步操作包装成返回 [error, result] 的形式,类似 Node.js 风格,让业务逻辑更线性:
- 手写轻量封装:
const to = p => p.then(res => [null, res]).catch(err => [err, null]) - 或使用成熟库如
await-to-js - 后续直接解构判断,不用嵌套 try/catch
示例:
const to = p => p.then(res => [null, res]).catch(err => [err, null]);
async function loadData() {
const [userErr, user] = await to(fetch('/api/user').then(r => r.json()));
const [postErr, posts] = await to(fetch('/api/posts').then(r => r.json()));
if (userErr) console.warn('用户加载失败', userErr);
if (postErr) console.warn('文章加载失败', postErr);
return { user, posts };
}
按需分层处理错误类型
不是所有错误都该同等对待。网络超时、401 权限失效、JSON 解析失败,应走不同路径:
- 网络层错误(断网、超时)→ 触发重试或 loading 中止
- 业务错误(401/403)→ 跳转登录或弹窗提示,不计入主错误日志
- 未预期错误(字段缺失、解析失败)→ 上报监控,保留堆栈
- 顶层保留
try/catch做 UI 层兜底,比如显示“加载失败,请重试”
不复杂但容易忽略。

















