await 本身不提供降级能力,但配合合理错误处理和备选逻辑可实现平滑降级:对关键异步操作单独 try/catch、按错误类型差异化兜底、用 ?. 和 ?? 防连锁崩溃、finally 清理副作用、主动上报+静默恢复。

await 本身不提供降级能力,但配合合理的错误处理和备选逻辑,就能在异步流程中实现平滑降级——即某一步失败时,不中断后续执行,也不让用户感知卡顿或空白。
只对关键异步操作单独 try/catch
不要把整个 async 函数体包进一个 try/catch,而是聚焦在最可能出错的那一步(比如 API 请求、数据库查询)上。这样失败只影响局部,其余逻辑照常运行。
- ✅ 正确:对 fetch 封装一层,单独捕获网络错误
- ❌ 错误:整个页面初始化函数用一个 try/catch,一出错就跳转 404 或清空所有状态
- 示例:请求用户信息失败时,显示默认头像和“游客”昵称,而不是让整个个人中心白屏
按错误类型提供差异化备选方案
不是所有失败都该用同一套兜底逻辑。网络超时、服务端 5xx、数据格式异常,应对方式应不同。
- 超时或连接拒绝 → 返回缓存数据或静态默认值
- 401/403 → 触发登录态刷新,再重试一次
- JSON 解析失败 → 记录日志并返回空对象,避免后续解构报错
- 可结合可选链(?.)和空值合并(??)防连锁崩溃,例如 user?.profile?.name ?? '未知用户'
用 finally 清理副作用,保持状态一致
降级不是“不管了”,而是有始有终。比如 loading 状态、临时锁、定时器,必须在成功、失败、取消三种路径下都归位。
- 在 await 前设 loading = true,无论是否出错,finally 里设 loading = false
- 若发起多个并发请求,某一个失败后,仍要确保其他请求结果能正常合并或渲染
- 避免因降级导致 UI 卡在“加载中”或按钮持续禁用
主动上报 + 静默恢复,兼顾监控与体验
用户不该为系统问题买单,但开发需要知道哪里弱。降级逻辑里加轻量日志上报,不阻塞主流程。
- 用 navigator.sendBeacon 或 Promise.race(上报请求, Promise.resolve()) 防止上报拖慢页面
- 同一类错误短时间内重复发生,可自动降级为更保守策略(如跳过个性化推荐,直接展示热门列表)
- 关键路径失败后,下次访问可预加载备用资源,提升下次成功率










