闭包实现请求重试机制,通过封装 retrycount 和 maxretries 实现自动递增与条件判断,支持指数退避、自定义重试逻辑、回调函数及 abortcontroller 可取消重试。

用闭包实现请求重试机制,核心是把「当前重试次数」和「最大重试次数」封装在闭包内,让每次失败后能调用同一个函数继续尝试,同时避免污染外部作用域。
封装可重试的 fetch 函数
闭包用来保存 retryCount(已重试次数)和 maxRetries(上限),每次调用内部函数时自动递增计数,并判断是否继续重试:
function createRetryableFetch(url, options = {}, maxRetries = 3) {
let retryCount = 0;
<p>return async function retryFetch() {
try {
const res = await fetch(url, options);
if (!res.ok) throw new Error(<code>HTTP ${res.status}</code>);
return res;
} catch (err) {
retryCount++;
if (retryCount 第 ${retryCount} 次重试中... ${delay}ms 后发起);
await new Promise(r => setTimeout(r, delay));
return retryFetch(); // 递归调用自身(仍在闭包作用域内)
}
throw err;
}
};
}</p><p>// 使用示例
const fetchWithRetry = createRetryableFetch('/api/data', { method: 'GET' }, 2);
fetchWithRetry().then(console.log).catch(console.error);
</p>支持自定义重试条件和回调
增强闭包参数,允许传入 shouldRetry(判断是否值得重试)、onRetry(重试前回调)等,提升灵活性:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
function createSmartRetryFetch(url, options = {}, config = {}) {
const {
maxRetries = 3,
shouldRetry = (err) => /network|failed|50\d/.test(err.message),
onRetry = (count, err) => console.warn(`重试 ${count}/${maxRetries}`, err),
baseDelay = 1000
} = config;
<p>let retryCount = 0;</p><p>return async function execute() {
try {
const res = await fetch(url, options);
if (!res.ok) throw new Error(<code>HTTP ${res.status}</code>);
return res;
} catch (err) {
retryCount++;
if (retryCount setTimeout(r, delay));
return execute();
}
throw err;
}
};
}
</p>避免闭包陷阱:注意 this 和引用问题
如果请求逻辑依赖 this 或外部变量,需确保闭包捕获的是稳定值:
- 用箭头函数或显式 bind 避免 this 丢失
- 不要在闭包外修改被引用的 options 对象,否则重试时可能带入意外状态
- 如需动态 url,建议把 url 生成逻辑放入闭包内(例如传入一个函数)
配合 AbortController 实现可取消重试
闭包还可封装 abortSignal,让整个重试链路支持手动中断:
function createAbortableRetryFetch(url, options = {}, maxRetries = 3) {
let retryCount = 0;
let controller = new AbortController();
<p>return {
async fetch() {
try {
const res = await fetch(url, { ...options, signal: controller.signal });
if (!res.ok) throw new Error(<code>HTTP ${res.status}</code>);
return res;
} catch (err) {
if (controller.signal.aborted) throw err;
retryCount++;
if (retryCount setTimeout(r, 1000));
return this.fetch();
}
throw err;
}
},
abort() {
controller.abort();
controller = new AbortController(); // 重置,便于下次调用
}
};
}
</p>Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










