javascript自定义重试器核心是将shouldretry函数作为参数解耦判断逻辑,支持基于错误类型、http状态码、响应字段等条件决定是否重试,并集成指数退避、幂等性校验与abortcontroller兼容等健壮特性。

JavaScript 中实现支持自定义判断条件的请求重试器,核心在于把“是否重试”从硬编码逻辑解耦为可传入的函数,同时控制重试次数、延迟和错误处理流程。下面是一种简洁、实用、可扩展的实现方式。
设计一个可配置的重试器函数
用高阶函数封装重试逻辑,接收原始请求函数、最大重试次数、延迟策略,以及最关键的 shouldRetry 判断函数:
-
shouldRetry 接收
error(或完整响应)和当前重试次数attempt,返回true表示应重试 - 支持判断 HTTP 状态码、网络错误类型、响应体字段(如
data?.code === 'BUSY')、超时等任意条件 - 避免对 4xx 错误(如 401、404)盲目重试,但可让调用方自行决定(例如 429 Too Many Requests 就该重试)
基础重试器实现(Promise 风格)
以下是一个轻量、无依赖的实现示例:
function createRetryer({ maxRetries = 3, baseDelay = 100, shouldRetry = () => true }) {
return async function retryableRequest(requestFn, ...args) {
let lastError;
for (let attempt = 0; attempt 0 && shouldRetry(null, attempt, result) === false) {
return result;
}
return result;
} catch (err) {
lastError = err;
if (attempt === maxRetries || !shouldRetry(err, attempt, null)) {
throw err;
}
// 指数退避 + 随机抖动(防雪崩)
const delay = Math.min(baseDelay * Math.pow(2, attempt) + Math.random() * 100, 3000);
await new Promise(r => setTimeout(r, delay));
}
}
throw lastError;
};
}
使用示例:
const fetchWithRetry = createRetryer({
maxRetries: 2,
shouldRetry: (err, attempt, response) => {
// 仅对网络错误、5xx、429 重试
if (!err) return false;
if (err.name === 'AbortError') return false; // 主动取消不重试
if (err.response?.status >= 500 || err.response?.status === 429) return true;
if (err.message.includes('NetworkError') || err.message.includes('Failed to fetch')) return true;
return false;
}
});
<p>// 调用
fetchWithRetry(fetch, '<a href="https://www.php.cn/link/46b315dd44d174daf5617e22b3ac94ca">https://www.php.cn/link/46b315dd44d174daf5617e22b3ac94ca</a>')
.then(data => console.log(data))
.catch(err => console.error('最终失败:', err));</p>
适配 Axios 或 Fetch 的实际封装
更贴近工程实践的做法是封装成中间件式工具:
- 对
axios:用拦截器 + 自定义 config 字段(如retry: { shouldRetry: ..., retries: 3 }) - 对
fetch:包装成新函数,透传 signal、headers,并允许传入shouldRetry回调 - 关键点:确保
shouldRetry能访问到完整的 error 对象(含 status、statusText、body)、response headers,甚至原始 URL 和 method
注意事项与进阶建议
避免踩坑,提升健壮性:
- 重试前检查是否已 abort(尤其配合 AbortController),防止无效等待
- 记录重试日志(如
console.warn(`Retry #${attempt} for ${url}`)),便于排查 - 对敏感操作(如 POST/PUT)重试需确认幂等性;非幂等请求建议加 idempotency key
- 可扩展支持「按错误类型分策略」:比如网络错误重试 3 次,429 错误重试 5 次并读取
Retry-After头
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











