可封装通用异步重试函数,支持错误捕获、次数/间隔控制、指数退避、自定义中断条件及AbortSignal取消;默认最大重试3次,初始延迟100ms,超时上限5000ms。

可以封装一个通用的异步重试函数,核心是捕获错误、控制重试次数与间隔,并支持自定义退避策略和中断条件。
基础重试包装函数
最简实用版本需包含:Promise 执行、错误捕获、重试计数、延迟等待。避免无限循环,必须设最大重试次数。
- 用 async/await 保证流程清晰,便于错误拦截
- 用 try/catch 捕获每次执行的 rejection
- 用 setTimeout 或 Promise.resolve().then(() => new Promise(resolve => setTimeout(resolve, delay))) 实现延迟(避免阻塞)
- 失败时递归调用自身,或用 while 循环 + await 控制流程
支持指数退避与自定义选项
生产环境应避免固定间隔重试(易引发雪崩),推荐指数退避(如 100ms → 200ms → 400ms),并允许传入超时、最大重试次数、初始延迟等参数。
- maxRetries 默认 3,0 表示不重试
- baseDelay 初始毫秒数,如 100
- maxDelay 防止退避过大,如 5000
- shouldRetry 可选函数,接收 error 和 attempt,返回布尔值决定是否继续重试(例如只重试网络错误)
集成 AbortSignal 支持取消
现代浏览器和 Node.js(v16+)支持 AbortController,可在重试中途主动中止,避免资源浪费。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
- 将 signal 传入原始异步操作(如 fetch、axios)
- 在重试循环中监听 signal.aborted,提前 throw new DOMException('Aborted', 'AbortError')
- 外部调用时可统一控制生命周期,比如页面卸载时 abort
完整示例(含类型提示)
以下是一个兼顾健壮性与可用性的实现:
async function retryAsync<T>(
fn: () => Promise<T>,
options: {
maxRetries?: number;
baseDelay?: number;
maxDelay?: number;
shouldRetry?: (error: unknown, attempt: number) => boolean;
signal?: AbortSignal;
} = {}
): Promise<T> {
const {
maxRetries = 3,
baseDelay = 100,
maxDelay = 5000,
shouldRetry = () => true,
signal
} = options;
<p>for (let attempt = 0; ; attempt++) {
try {
if (signal?.aborted) {
throw Object.assign(new Error('Request aborted'), { name: 'AbortError' });
}
return await fn();
} catch (err) {
if (attempt >= maxRetries || !shouldRetry(err, attempt)) {
throw err;
}</p><pre class='brush:php;toolbar:false;'> const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
await new Promise(resolve => setTimeout(resolve, delay));
}} }
使用方式:const data = await retryAsync(() => fetch('/api/data').then(r => r.json()), { maxRetries: 2 });

















