js retry 实现
实现 JavaScript 重试机制的方法
方法一:基于 Promise 和递归的简单重试
function retry(fn, maxRetries, delay) {
return new Promise((resolve, reject) => {
const attempt = (retryCount) => {
fn()
.then(resolve)
.catch((error) => {
if (retryCount >= maxRetries) {
reject(error);
return;
}
setTimeout(() => attempt(retryCount + 1), delay);
});
};
attempt(0);
});
}
方法二:支持指数退避的重试策略

function retryWithBackoff(fn, maxRetries, initialDelay) {
return new Promise((resolve, reject) => {
const attempt = (retryCount) => {
fn()
.then(resolve)
.catch((error) => {
if (retryCount >= maxRetries) {
reject(error);
return;
}
const delay = initialDelay * Math.pow(2, retryCount);
setTimeout(() => attempt(retryCount + 1), delay);
});
};
attempt(0);
});
}
方法三:支持自定义条件判断的重试

function retryWithCondition(fn, maxRetries, shouldRetry) {
return new Promise((resolve, reject) => {
const attempt = (retryCount) => {
fn()
.then(resolve)
.catch((error) => {
if (retryCount >= maxRetries || !shouldRetry(error)) {
reject(error);
return;
}
setTimeout(() => attempt(retryCount + 1), 0);
});
};
attempt(0);
});
}
方法四:使用 async/await 语法实现
async function asyncRetry(fn, maxRetries, delay) {
let lastError;
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
lastError = error;
if (delay > 0) {
await new Promise((r) => setTimeout(r, delay));
}
}
}
throw lastError;
}
方法五:封装为可配置的重试工具函数
function createRetry(options = {}) {
const {
maxRetries = 3,
delay = 1000,
backoffFactor = 1,
shouldRetry = () => true
} = options;
return async function retry(fn) {
let lastError;
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
lastError = error;
if (i === maxRetries - 1 || !shouldRetry(error)) {
throw lastError;
}
const currentDelay = delay * Math.pow(backoffFactor, i);
await new Promise((r) => setTimeout(r, currentDelay));
}
}
};
}
使用示例
// 示例1: 基本使用
retry(() => fetch('https://api.example.com/data'), 3, 1000)
.then(console.log)
.catch(console.error);
// 示例2: 使用指数退避
retryWithBackoff(() => someAsyncOperation(), 5, 1000)
.then(console.log)
.catch(console.error);
// 示例3: 使用条件判断
retryWithCondition(
() => axios.get('/api'),
3,
(error) => error.response?.status === 429
);
// 示例4: 使用配置化的重试函数
const customRetry = createRetry({
maxRetries: 5,
delay: 500,
backoffFactor: 2,
shouldRetry: (error) => error.code !== 'PERMANENT_ERROR'
});
customRetry(() => callExternalService())
.then(console.log)
.catch(console.error);
注意事项
- 重试机制适用于暂时性错误(如网络波动),不适用于永久性错误
- 对于幂等操作可以安全重试,非幂等操作需谨慎
- 考虑设置合理的重试次数和延迟时间,避免无限重试
- 在浏览器环境中使用时,注意用户可能离开页面导致重试中断





