async/await 本身不增强健壮性,健壮性源于对错误、超时、重试和并发的主动设计,需在每个关键异步步骤单独 try/catch,用 AbortController 控制超时,按错误类型实施指数退避重试,并合理选用 Promise.allSettled 等并发策略。

async/await 本身不增强健壮性,健壮性来自你对错误、超时、重试和并发的主动设计。关键不是“怎么写 await”,而是“在哪加 try、怎么设 timeout、失败后要不要重、多个请求怎么排”。
显式错误处理:每个 await 都该有边界
未捕获的 Promise rejection 会直接抛出,中断整个调用链。尤其在多层依赖中,一个接口失败不该让整个页面白屏。
- 每个关键异步步骤单独 try/catch,避免“一错全错”;
- 非关键操作(如埋点、日志)用 silent catch:
await trackEvent().catch(() => {}); - fetch 默认不 throw 4xx/5xx,必须手动检查
response.ok或res.status >= 200 && res.status < 300; - 聚合多个请求时,优先用
Promise.allSettled而非Promise.all,确保部分失败不影响其他结果。
超时控制:不能只靠 Promise.race
原生 async/await 没有 timeout 语法,硬套 Promise.race([fetch(), timeout()]) 容易导致资源泄漏——比如 fetch 已发出去但被 race 掉,后续仍可能 resolve,干扰状态。
- 搭配
AbortController使用:传{ signal }给 fetch,超时触发controller.abort(); - 避免在 timeout 后继续 await 原始 Promise,应统一用被 abort 的 signal 控制生命周期;
- 不同接口设不同超时阈值:读操作建议 8s,写操作可设 15s,并在错误对象里带上路径和参数摘要,方便定位瓶颈。
重试策略:不是循环 + delay 就完事
简单 while 重试在服务雪崩或网络分区时反而加剧问题,需兼顾退避、熔断和错误分类。
- 采用指数退避:间隔从 100ms → 200ms → 400ms 递增;
- 限制最大次数(通常 3–5 次),并区分错误类型:连接拒绝、503 可重试;401、403、422 等业务错误立即终止;
- 引入简易熔断:连续 3 次失败后暂停 30 秒,期间直接 reject,不发起新请求;
- 每次重试记录序号、错误码、耗时,便于判断是偶发抖动还是真故障。
并发协调:选对 Promise 方法,管住“同时发多少”
并发不是越多越好。浏览器默认限制同域并发请求数(通常 6 个),盲目 Promise.all 100 个请求会排队、超时、内存飙升。
- 强顺序依赖(如 A 结果是 B 输入)不用 all,改用串行 await 或 reduce 链式调用;
- 弱依赖或独立请求,用
Promise.allSettled并分批控制:例如每 5 个一组,等 batch 完再发下一组; - 防重复提交和竞态:每次新请求生成新
AbortController,旧请求先 abort 再发新请求; - 非关键副作用(如缓存写入、本地存储)可 fire-and-forget:不 await、不 catch,避免拖慢主流程。

















