关键在于用带抖动的指数退避替代固定延迟,优先响应retry-after头,按错误类型分级处理重试,限制次数(3~5次)并配合abortcontroller取消机制。

关键不是多试几次,而是让每次重试都错开节奏、避开拥堵、尊重服务状态。
用带抖动的指数退避替代固定间隔
纯固定延迟(比如每次都等1秒)会让大量客户端在整点时刻集中重试,形成“重试风暴”。指数退避让等待时间随失败次数翻倍,再叠加随机抖动,能有效打散请求峰值。
- 第1次失败后:等待 Math.random() * 1000 ms(0–1秒)
- 第2次失败后:等待 Math.random() * 2000 ms(0–2秒)
- 第3次失败后:等待 Math.random() * 4000 ms(0–4秒)
- 建议上限设为 30 秒,防止用户长时间无响应
优先响应服务端限流信号
后端在高负载时会主动通过 HTTP 响应头告诉你“别急着来”,忽略这些信号等于硬撞红灯。
- 检查 Retry-After 头:若值为数字,直接按秒转毫秒;若为时间字符串,用
Date.parse()算出距当前时间的毫秒差 - 对 429 或 503 响应,优先采用该头指定的等待时间,而不是走客户端默认退避逻辑
- 没有 Retry-After 时,再 fallback 到指数退避 + 抖动策略
按错误类型分级处理,避免无效重试
不是所有失败都值得重试。盲目重试 400、401、404 这类客户端错误,只会浪费带宽和服务器资源。
- 可重试:网络异常(TypeError / "Failed to fetch")、503、504、部分 500(尤其伴随 "overloaded" 提示时)
- 不重试:400、401、403、404、422 等明确由客户端导致的错误
- 谨慎重试:非幂等 POST 请求(如创建订单),除非服务端支持幂等性(如提供 Idempotency-Key)
限制重试次数并配合取消机制
不限次数的重试可能把长尾请求堆满队列,尤其在用户已离开页面时,还在后台发请求毫无意义。
- 最大重试次数建议设为 3~5 次,移动端可进一步收紧到 2~3 次
- 每次发起请求前创建 AbortController,并在重试前检查
signal.aborted - 页面卸载或组件销毁时调用
controller.abort(),清理所有待处理定时器和 pending 请求
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











