重试失败后应立即触发降级兜底,而非等待全部重试完成;需将兜底嵌入重试逻辑作为自然终点,按错误类型差异化响应,并确保兜底可执行、有状态记忆且必被执行。

重试失败后触发降级兜底,关键不是“等重试全完再处理”,而是把降级设计成重试流程的自然终点——每次重试尝试都应明确知道“如果这次也失败,下一步该做什么”。
重试逻辑里嵌入兜底入口点
不要把重试和降级写成两个割裂阶段。在封装重试函数时,直接预留兜底回调参数,让最后一次失败自动触发它:
- 用 Promise 封装 fetch 请求,内部维护 attempt 计数器
- 当 attempt 达到最大次数(如 3 次)且仍 reject,不再递归重试,而是调用传入的 fallback 函数
- fallback 可返回默认数据、渲染备用 UI、跳转提示页,或触发用户可操作路径(如手动输入)
按错误类型差异化走降级路径
不是所有失败都该走同一套兜底。捕获拒绝原因后,针对性响应更可靠:
- 网络中断或 AbortError:优先 fallback 到本地缓存数据或上次成功结果
- 401 / 403:说明身份失效,降级为跳转登录页,不重试
- 503 / 504:服务不可用,可显示“系统繁忙中”,并提供离线可用功能入口
- JSON 解析失败或空响应:用内置默认文案对象兜底,避免页面因结构缺失崩溃
兜底方案本身要可执行、有状态记忆
一个“定位失败,请重试”的提示不是兜底,只是一个放弃声明。真正有效的降级需带行为和上下文:
立即学习“Java免费学习笔记(深入)”;
- IP 地理定位作为 fallback:调用 ipapi.co 或类似轻量接口,获取城市级位置,哪怕不准也比空白强
- 记住用户上次手动选择的位置(存 localStorage + 时间戳),超时(如 24 小时)前直接复用
- 对强依赖位置的功能(如外卖下单),降级为引导用户去系统设置开启权限,并附简短动图说明
- 所有兜底动作同步上报监控,标记来源为 “retry_exhausted”,便于后续分析是否需调整重试策略
避免兜底被意外跳过
常见疏漏是兜底逻辑写了,但没确保它一定被执行:
- 用 try/catch 包裹异步重试主流程,catch 块必须包含 fallback 调用,防止未捕获异常吞掉兜底机会
- 若使用 AbortController 控制请求生命周期,重试前检查 signal.aborted,已中止则立即进入兜底,不浪费一次重试配额
- 全局监听 unhandledrejection,作为兜底的最后防线——万一某处漏了 catch,至少还能记录、上报、展示通用错误页


















