可封装带重试逻辑的 promise 函数,需传入返回 promise 的工厂函数、最大重试次数及可选延迟毫秒数,通过递归尝试直至成功或耗尽次数,支持指数退避与自定义错误判断。

可以在 Promise 外层封装一个带重试逻辑的函数,通过递归或循环控制最大重试次数,并在每次失败后延迟重试(可选),直到成功或耗尽重试次数。
基础重试包装函数(支持次数限制)
核心思路是:接收原始 Promise 工厂函数(返回 Promise 的函数)、最大重试次数、可选延迟毫秒数;失败时递归调用自身,减少剩余次数;成功则 resolve,失败次数用尽则 reject 最终错误。
- 必须用“工厂函数”而非直接传 Promise,否则会立即执行、无法重试
- 推荐使用 setTimeout 实现简单延迟,避免阻塞事件循环
- 首次调用传入 retryCount > 0,为 0 时直接拒绝(兜底)
代码示例(无依赖、ES6+)
以下是一个简洁可靠的实现:
function retryPromise(fn, maxRetries = 3, delayMs = 1000) {
return new Promise((resolve, reject) => {
function attempt(retryLeft) {
fn()
.then(resolve)
.catch(err => {
if (retryLeft attempt(retryLeft - 1), delayMs);
}
});
}
attempt(maxRetries);
});
}
使用方式:
// 模拟可能失败的异步操作
const apiCall = () => fetch('/api/data').then(r => {
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return r.json();
});
<p>// 最多重试 2 次(共执行 3 次),每次间隔 1.5 秒
retryPromise(apiCall, 2, 1500)
.then(data => console.log('Success:', data))
.catch(err => console.error('Gave up after retries:', err));</p>
增强版:支持指数退避与自定义判断
实际场景中常需更精细控制,比如只对特定错误重试、延迟随次数增长(指数退避)、取消重试等。可扩展如下:
- 增加 shouldRetry 回调,决定是否对当前错误重试(如忽略 401 或 404)
- 延迟改为 delayMs * 2^attemptIndex 实现指数退避
- 传入 signal(AbortSignal)支持外部取消
注意事项
容易出错的地方:
- 直接传
Promise而非函数 → 执行时机失控,重试无效 - 忘记处理
maxRetries === 0边界情况 → 无限递归或未 reject - 未清理定时器(尤其配合 AbortSignal 时)→ 内存泄漏或误触发
- 错误堆栈丢失 → 建议在 reject 前保留原始 error 的 stack(可用
err.stack或new Error(...)包装)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











