加载失败自动重试时怎么避免触发无限循环?

IT人莉莉 阅读 68

我现在在做数据加载失败的自动重试功能,想实现失败三次后弹出提示。但写了个递归调用fetch的函数,发现请求次数会一直增加,控制台还报了Maximum call stack error。试过用setTimeout包裹递减重试次数,但有时候还是会卡死循环…

看了文档说要用防抖函数,但具体怎么结合重试次数控制呢?比如在axios拦截器里加逻辑,怎么避免重复触发和状态混乱?

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
Prog.柚溪
应该是递归没控制好退出条件。别用递归,改用带重试计数器的普通函数配合setTimeout,比如:

async function fetchWithRetry(url, maxRetries = 3) {
try {
const response = await axios.get(url);
return response.data;
} catch (error) {
if (maxRetries > 0) {
await new Promise(resolve => setTimeout(resolve, 1000));
return fetchWithRetry(url, maxRetries - 1);
}
throw new Error('Max retries reached');
}
}


axios拦截器里加个retryCount参数就行,记得把重试间隔调大点避免高频请求
点赞
2026-03-07 03:05
技术志鸽
这种情况我之前也遇到过,确实容易搞成无限递归或者堆栈溢出。别用单纯的递归了,直接用一个计数器配合异步队列控制重试次数。

给你个简单靠谱的实现方式,在Axios拦截器里可以用Promise的延时机制来避免无限循环:

let retryCount = 0;
axios.interceptors.response.use(null, async function (error) {
const config = error.config;
if (!config || retryCount >= 3) {
return Promise.reject(error);
}

retryCount++;
try {
await new Promise(resolve => setTimeout(resolve, 1000)); // 防止过于频繁重试
return axios(config); // 重新发起请求
} catch (e) {
if (retryCount === 3) {
alert('请求失败,请检查网络');
}
return Promise.reject(e);
}
});

// 别忘了每次请求开始时重置计数器
axios.interceptors.request.use(config => {
retryCount = 0;
return config;
});


关键点就是用一个全局变量retryCount来控制重试次数,每次请求开始前清零,失败时递增。通过setTimeout加个延迟,防止过于密集的重试导致浏览器卡死。

如果你用WordPress的REST API,记得在服务器端也设置合理的超时和错误处理逻辑,避免前端一直重试但后端根本没响应的情况。这种问题调试起来真够头疼的,我深有体会...
点赞 21
2026-01-29 11:09