JavaScript中实现请求失败自动重试三次的核心是捕获错误、判断是否重试、控制次数与间隔;常用async/await递归封装fetch,失败时延时重试,最终抛出最后一次错误。

JavaScript 中实现请求失败自动重试三次,核心是捕获错误、判断是否重试、控制重试次数和间隔。不依赖第三方库也能轻松做到。
用 async/await 封装 fetch 并递归重试
这是最常用也最清晰的方式:把请求逻辑封装成一个可重试的异步函数,失败时调用自身,传入剩余重试次数。
- 初始调用传入最大重试次数(如 3)
- 每次失败后,若还有剩余次数,等待一段时间再重试
- 使用 setTimeout 或 Promise.resolve().then() 控制延迟(推荐 setTimeout 避免阻塞)
- 所有重试都失败时,抛出最后一次错误,便于上层统一处理
async function requestWithRetry(url, options = {}, maxRetries = 3) {
try {
const res = await fetch(url, options);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return await res.json();
} catch (err) {
if (maxRetries <= 0) throw err;
await new Promise(resolve => setTimeout(resolve, 1000)); // 等待 1s
return requestWithRetry(url, options, maxRetries - 1);
}
}
<p>// 使用
requestWithRetry('/api/data')
.then(data => console.log(data))
.catch(err => console.error('最终失败:', err));
用 Promise 链 + 循环实现非递归重试
避免递归调用栈过深(极端情况),可用 while 循环 + Promise 链手动控制重试流程。
- 定义 retryCount 和 delayMs,每次失败后递减并延时
- 用 Promise 链串联请求,失败则进入下一轮,成功则 resolve 结果
- 适合需要更精细控制重试逻辑(比如按错误类型决定是否重试)的场景
function requestWithLoop(url, options = {}, maxRetries = 3) {
let retryCount = maxRetries;
let lastErr;
<p>return new Promise((resolve, reject) => {
function attempt() {
fetch(url, options)
.then(res => {
if (res.ok) return res.json();
throw new Error(<code>HTTP ${res.status}</code>);
})
.then(resolve)
.catch(err => {
lastErr = err;
if (retryCount > 0) {
retryCount--;
setTimeout(attempt, 1000);
} else {
reject(lastErr);
}
});
}
attempt();
});
}
根据错误类型决定是否重试
不是所有错误都适合重试——网络中断、503 服务不可用可以重试;401 未授权、404 不存在一般不该重试。
立即学习“Java免费学习笔记(深入)”;
- 检查 err.name === 'TypeError'(常见于网络断开)或 res.status 在 [500, 599] 区间
- 对 4xx 错误通常直接 reject,不重试
- 可在 catch 中加条件判断:if (shouldRetry(err)) { ... } else throw err
加入指数退避(可选进阶)
连续重试时,避免雪崩式请求,让每次等待时间逐渐变长(如 1s → 2s → 4s)。
- 计算延迟:delay = Math.pow(2, maxRetries - currentRetries) * 1000
- 可配合随机抖动(+ Math.random() * 200)进一步降低冲突概率
- 对高并发或服务端较弱的接口更友好
不复杂但容易忽略的是错误分类和退避策略。简单场景用递归封装够用,生产环境建议加上状态判断和退避机制。


















