通过封装一个支持配置重试次数、间隔和触发条件的异步函数,可以在调用 fetch 时自动处理网络波动或临时错误。具体做法是定义一个包含最大重试次数、当前重试计数和指数退避逻辑的循环,在捕获到特定 http 状态码(如 503)或网络异常时,等待指定时间后重新发起请求,直到成功或达到上限抛出最终错误。

如何根据 HTTP 状态码决定是否需要重试
判断是否重试的核心在于检查响应对象的 status 属性,通常将 5xx 服务端错误或 429 限流错误视为可重试条件。在代码实现中,需要解析 fetch 返回的 Promise,若未抛出异常则提取状态码进行比对,只有当状态码落在预设的重试白名单内时才执行等待并继续下一轮循环,否则直接返回结果或报错。

async function fetchWithRetry(url, options = {}) {
const maxRetries = options.maxRetries || 3;
let attempt = 0;
while (true) {
try {
const response = await fetch(url, options);
// 检查是否为可重试的状态码
if (response.ok || ![500, 502, 503, 504, 429].includes(response.status)) {
return response;
}
// 如果是可重试的错误,增加尝试次数
attempt++;
if (attempt >= maxRetries) {
throw new Error(`Request failed after ${maxRetries} retries`);
}
// 计算退避时间
const delay = Math.pow(2, attempt) * 1000;
console.log(`Retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
} catch (error) {
// 网络错误或其他异常也进行重试
attempt++;
if (attempt >= maxRetries) {
throw error;
}
const delay = Math.pow(2, attempt) * 1000;
console.log(`Network error, retrying in ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
// 使用示例
fetchWithRetry('https://api.example.com/data', { maxRetries: 3 })
.then(res => res.json())
.then(console.log);
如何实现指数退避等待机制
为了避免在服务器恢复期间造成二次压力,重试间隔不应固定,而应采用指数退避策略。即在每次重试失败后,将等待时间按倍数递增,例如第一次等 2 秒,第二次等 4 秒。在 JavaScript 中,可以通过 Math.pow(2, attempt) 计算延迟毫秒数,并结合 setTimeout 包装为 Promise 来实现非阻塞等待,确保主线程不被长时间挂起。

// 核心退避逻辑片段 const baseDelay = 1000; // 基础延迟 1 秒 const delay = Math.min(Math.pow(2, attempt) * baseDelay, 30000); // 最大不超过 30 秒 await new Promise(resolve => setTimeout(resolve, delay));
如果请求被取消会怎样处理
当用户在重试等待期间主动取消请求(例如通过 AbortController),fetch 会抛出一个名为 AbortError 的异常。在上述封装逻辑中,这个异常会被 catch 块捕获。由于 AbortError 属于用户主动行为而非网络故障,通常不应将其计入有效重试次数,或者应直接向上抛出以终止后续操作,避免无意义的重试消耗资源。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











