用 Promise + 递归实现请求重试的核心是失败时不直接 reject,而是延迟后递归调用自身,并控制次数、指数退避延迟(含抖动与上限)、AbortSignal 取消及封装为可复用高阶函数。

用 Promise + 递归实现请求重试,核心是让失败时不是直接 reject,而是调用自身重试,同时控制次数、延迟和退避策略。
基础结构:带次数限制的递归重试
每次请求失败后,判断是否还有重试机会。有则延迟后重试,否则抛出最终错误。
- 用参数记录当前重试次数(retryCount)和最大重试次数(maxRetries)
- 失败时用 setTimeout 延迟执行下一次调用,避免阻塞
- 成功直接 resolve 结果;失败且达上限则 reject 错误
示例:
function fetchWithRetry(url, options = {}, retryCount = 0, maxRetries = 3) {
return fetch(url, options)
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(err => {
if (retryCount >= maxRetries) throw err;
return new Promise(resolve => {
setTimeout(() => {
resolve(fetchWithRetry(url, options, retryCount + 1, maxRetries));
}, 1000);
});
});
}
加入指数退避:避免雪崩式重试
连续快速重试可能加重服务压力。改用指数增长延迟(如 1s → 2s → 4s),更友好也更有效。
- 延迟时间 = baseDelay * 2^retryCount,常用 baseDelay 为 100~1000ms
- 可加随机抖动(jitter),防止大量请求同步重试
- 注意数值溢出,设置最大延迟上限(如 10s)
改进版延迟逻辑:
const getDelay = (retryCount, base = 1000) => {
const delay = base * Math.pow(2, retryCount);
const jitter = Math.random() * 200; // ±200ms 抖动
return Math.min(delay + jitter, 10000); // 不超过 10 秒
};
支持取消与 AbortController
真实场景中,用户可能在重试中途离开页面或取消操作。需支持主动中断。
将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。
- 接收 AbortSignal 并透传给 fetch
- 在 setTimeout 前检查 signal 是否已中止
- 中止时立即 reject 并清理定时器(需保存 timerId)
关键点:不能只靠 fetch 的 signal 中断网络请求,还要阻止后续 setTimeout 触发递归。
封装成可复用工具函数
把重试逻辑抽离为高阶函数,接受原始请求函数,返回增强版函数,便于复用和测试。
- 参数包括:原始函数、最大重试次数、退避配置、自定义错误判断(如只对 5xx 重试)
- 返回函数保持与原函数签名一致,便于替换
- 可结合 async/await 写法,更贴近直觉(内部仍用 Promise 递归)
例如:
const withRetry = (fn, { maxRetries = 3, baseDelay = 1000 } = {}) => {
return async function(...args) {
let lastError;
for (let i = 0; i
setTimeout(r, getDelay(i, baseDelay))
);
}
}
throw lastError;
};
};
<p>// 使用
const safeFetch = withRetry(fetch, { maxRetries: 2 });</p>不复杂但容易忽略细节。关键是把“失败→延迟→再试”这个循环用 Promise 链自然表达,而不是强行用 while 或递归+回调混搭。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










