JS请求重试机制需按错误类型区分处理:网络错误可重试,401/429等按场景决定,400/500等通常不重试;推荐axios拦截器实现指数退避重试,或手写retry函数;应集成离线感知、用户提示与可观测性。

JS 中实现请求重试机制,核心在于“可控失败后自动补救”,不是盲目循环,而是结合错误类型、退避策略、最大尝试次数和业务语义做判断。下面从设计思路到可落地的实战项目结构,分步说明。
明确重试触发条件
不是所有失败都该重试。需区分三类错误:
-
网络层错误:如
Network Error、timeout、Failed to fetch—— 适合重试 -
服务端明确拒绝:如
401 Unauthorized(需刷新 token)、403 Forbidden、429 Too Many Requests—— 按场景决定是否重试(429 可重试并读取Retry-After) -
客户端或业务错误:如
400 Bad Request、422 Unprocessable Entity、500 Internal Server Error(部分场景下可能持续失败)—— 通常不重试,应交由上层处理
选择或封装一个支持重试的 HTTP 客户端
推荐优先使用 axios(浏览器 + Node.js 兼容),它原生支持拦截器与配置扩展,且生态成熟:
- 安装:
npm install axios - 创建带重试能力的实例,例如设置默认重试次数为 3,指数退避(100ms → 200ms → 400ms)
- 用拦截器在响应失败时捕获错误,判断是否满足重试条件,再递归发起请求(注意避免无限递归)
手写轻量级重试工具函数(适合无框架或定制需求)
不依赖第三方库时,可用 Promise + setTimeout 实现通用重试逻辑:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
function retry(fn, options = {}) {
const { maxRetries = 3, baseDelay = 100, backoff = 2 } = options;
<p>return function attempt(...args) {
return fn(...args).catch((err) => {
if (maxRetries </p><pre class="brush:php;toolbar:false;"> // 只对网络类错误重试(可根据 error.code / message 进一步细化)
if (!/network|timeout|fetch/i.test(err.message)) throw err;
const delay = baseDelay * Math.pow(backoff, maxRetries - 1);
console.warn(`请求失败,${delay}ms 后重试(剩余 ${maxRetries} 次)`);
return new Promise(resolve => setTimeout(() => resolve(), delay))
.then(() => attempt(...args));
});}; }
// 使用示例 const fetchUser = retry(() => axios.get('/api/user/123'), { maxRetries: 2 }); fetchUser().then(data => console.log(data)).catch(err => console.error(err));
集成离线状态感知(增强鲁棒性)
单纯重试不够智能。建议配合 Offline.js 或原生 navigator.onLine 检测:
- 当检测到离线时,暂停所有非关键请求,避免无效重试
- 上线后自动重放队列中的待发请求(可结合任务队列实现)
- 用户界面上显示“正在重连…”提示,提升体验
记录与可观测性(生产必备)
重试不是黑盒操作。建议加入简单日志或埋点:
- 记录每次重试的 URL、HTTP 方法、错误原因、重试序号
- 统计重试成功率(如:100 次请求中 87 次首试成功,13 次经 1–2 次重试成功)
- 发现高频重试接口,及时推动后端排查稳定性问题
不复杂但容易忽略










