Ajax重试采用指数退避策略,即失败后延迟时间按2ⁿ倍增(如1s→2s→4s),并设最大重试次数与延迟上限,结合fetch与AbortController实现可控重试与请求取消。

Ajax 请求重试时采用延迟递增策略(也叫指数退避),是为了避免在服务不稳定时持续高频重试,加重服务器压力或触发限流。核心思路是:每次失败后,等待时间按倍数增长(如 1s → 2s → 4s → 8s),并设置最大重试次数和最大延迟上限。
基础实现:用 Promise + setTimeout 封装重试逻辑
不依赖第三方库,纯 JavaScript 可以这样组织:
- 将 Ajax 请求(如 fetch)包装成可重试的 Promise 函数
- 每次失败时,计算下一次延迟时间(例如:delay = Math.min(baseDelay * 2 ** attempt, maxDelay))
- 用 setTimeout 控制延迟,并递归调用自身(或用循环 + await)
关键参数要合理设置
实际使用中这几个值需要根据业务场景权衡:
- baseDelay:首次重试前等待时间,建议 500ms ~ 1s
- maxRetries:最大重试次数,通常 3~5 次足够,太多可能用户已离开页面
- maxDelay:延迟上限(防止 2ⁿ 增长失控),比如限制在 10s 内
- 只对特定错误码重试(如网络断开、502/503/408),跳过 400/401/404 等客户端错误
结合 fetch 实现一个可用示例
下面是一个带指数退避的 fetch 封装函数:
立即学习“Java免费学习笔记(深入)”;
async function fetchWithRetry(url, options = {}, { baseDelay = 1000, maxRetries = 3, maxDelay = 10000 } = {}) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
const res = await fetch(url, options);
if (res.ok) return res;
// 只对临时性错误重试
if (![502, 503, 504, 408].includes(res.status)) throw new Error(`HTTP ${res.status}`);
} catch (err) {
if (attempt === maxRetries) throw err;
}
const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
await new Promise(r => setTimeout(r, delay));
}
}调用时:// 示例:请求失败会按 1s → 2s → 4s 延迟重试fetchWithRetry('/api/data', { method: 'POST' })
进阶考虑:取消重复请求与 AbortController
用户快速多次触发同一请求时,旧请求应被取消,避免资源浪费:
- 每次调用生成新的 AbortController,把 signal 传给 fetch
- 重试前调用 controller.abort() 终止上一次未完成的请求
- 注意:需在重试循环内管理 controller 生命周期,不能全局复用


















