关键在于控制重试边界与资源占用:需结合指数退避(100ms起,上限5–10秒)、独立定时器、请求级状态管理、唯一标识、取消检查、weakmap元数据存储、熔断机制(如60秒内5次失败)、超时监控及内存清理(避免大对象闭包、及时释放资源)。

关键在于控制重试的边界条件和资源占用,而不是单纯依赖次数限制。
设置最大重试次数与退避策略
仅设固定重试次数(如 3 次)不够稳健,需结合指数退避(exponential backoff)避免密集重试。每次失败后延迟递增,既降低服务压力,也防止短时间内大量定时器/请求对象堆积。
- 推荐起始延迟 100ms,每次翻倍(100ms → 200ms → 400ms),上限建议 5–10 秒
- 用 setTimeout 而非 setInterval,确保每次重试都是独立调度,避免多个未清除定时器共存
- 重试计数应作为函数参数或闭包变量传递,避免闭包外状态被意外修改
限制并发与生命周期管理
重试逻辑若在多个请求间共享状态(如全局重试队列),容易因异常积压引发内存泄漏。每个请求应独立管理自身重试上下文。
- 为每次请求生成唯一标识(如 timestamp + random),用于日志追踪和调试
- 在重试前检查当前请求是否已被取消(例如通过 AbortController.signal.aborted)
- 使用 WeakMap 存储与请求绑定的元数据(如已重试次数、上次时间戳),避免强引用阻止垃圾回收
监控与主动熔断
客户端无法预知网络何时恢复,但可感知异常模式。当连续失败伴随高延迟或特定错误码(如 503、timeout、Network Error),应提前终止重试。
- 记录每次重试的耗时与响应状态,若连续 2 次超时 > 8s,直接 reject 并抛出 “RetryAborted” 错误
- 对同一 endpoint 在短时间(如 60 秒)内累计失败 ≥ 5 次,触发临时熔断(缓存拒绝窗口),后续请求直接失败不重试
- 在 catch 块中显式清理:清除定时器、释放 Blob / ArrayBuffer 引用、移除事件监听器(如有)
避免闭包陷阱与内存驻留
常见错误是将大对象(如完整 response body、File 对象、大型 JSON 数据)闭包进重试回调,导致无法被 GC 回收。
- 重试函数只保留必要字段(如 url、method、retryCount),不携带原始 payload 的深拷贝
- 上传类请求慎用重试:若已发送部分分片,应改用断点续传协议,而非整包重发
- 使用 finalizationRegistry(需环境支持)或 onabort/onloadend 回调做最后清理,作为兜底保障
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











