多个 await 默认串行执行,promise.all 并行但一损俱损;可用 promise.allsettled 或每个 fetch 后加 catch 转安全值,并注意 .json() 也可能抛错。

多个 await 默认是串行执行,不是并行——所以“多个 await 并行执行”本身是个常见误解。真正导致数据塌陷的,其实是用 Promise.all() 等待一批请求时,其中某一个被 reject,整个 Promise 就失败,后续逻辑中断,页面拿不到任何数据。
明确区分:串行 await vs 并行 Promise
这是问题根源。比如下面写法是串行,一个失败,后面全停:
await fetch('/user')await fetch('/orders')await fetch('/profile')
而下面才是并行,但默认“一损俱损”:
const [user, orders, profile] = await Promise.all([fetch(...), fetch(...), fetch(...)])
一旦任一 fetch 失败(网络错误、404、500),Promise.all 立即 reject,整个解构赋值失败,变量全 undefined,视图渲染就塌了。
用 Promise.allSettled() 保底所有结果
它会等所有 Promise 结束(无论成功或失败),返回一个固定结构的数组,每个元素带 status: 'fulfilled' | 'rejected' 和对应 value 或 reason。
- 适合需要“尽力而为”的场景:用户资料加载失败,但订单和设置仍要展示
- 返回值可统一处理,不会中断流程
- 示例中即使第三个请求失败,前两个数据仍可用
给每个 Promise 单独加 catch,转成“安全值”
如果仍想用 Promise.all(比如需要全部成功才继续),又不想被单个失败拖垮,就在每个 Promise 后链式调用 .catch(),把错误兜住,返回默认值:
fetch('/user').then(r => r.json()).catch(() => null)fetch('/orders').then(r => r.json()).catch(() => [])fetch('/profile').then(r => r.json()).catch(() => ({ theme: 'light' }))
这样 Promise.all 拿到的永远是三个“正常值”,不会 reject,解构安全,渲染不塌。
注意 .json() 自身也可能 throw
fetch 成功(状态码 200)不代表响应体是合法 JSON。直接 await res.json() 可能因格式错误抛出 SyntaxError,这常被忽略。
- 正确做法:在
.json()后也加.catch,或包在 try/catch 里 - 例如:
fetch(...).then(r => r.json().catch(e => { console.warn('JSON 解析失败', e); return null; }))











