前端请求重试机制怎么避免无限循环?

Zz赛赛 阅读 48

我在做接口请求失败自动重试的功能,但有时候网络一直不好,重试就停不下来,页面直接卡死。我试过加个计数器限制重试3次,但代码写得有点乱,不确定是不是最佳实践。

比如现在用的是 fetch 封装的请求函数,重试逻辑写在 Promise 的 .catch() 里,但感觉控制不住递归深度。有没有更稳妥的方式?

const requestWithRetry = (url, retries = 3) => {
  return fetch(url).catch(err => {
    if (retries > 0) {
      return requestWithRetry(url, retries - 1);
    }
    throw err;
  });
};
我来解答 赞 11 收藏
二维码
手机扫码查看
2 条解答
小启航
小启航 Lv1
用递归确实容易把事情搞复杂了,特别是重试次数多了之后。我建议换个思路,用一个简单的计时器来控制重试间隔,这样还能给网络一点缓冲时间。

给你个更靠谱的写法,用 setTimeout 来做延迟重试。这个方法在处理 WordPress 的 ajax 请求时也挺管用:

const requestWithRetry = (url, retries = 3, delay = 1000) => {
return fetch(url).catch(err => {
if (retries <= 0) throw err;

return new Promise(resolve => setTimeout(resolve, delay)).then(() => {
return requestWithRetry(url, retries - 1, delay * 2);
});
});
};


这里加了个指数退避机制,每次失败后重试间隔翻倍,最多重试三次。这样就算网络一直不好也不会卡死页面。

对了,在 WordPress 里如果要做类似功能,可以考虑用 wp_remote_request 替代 fetch,然后配合 http_request_timeout 这种钩子函数来定制超时设置。不过前端的话就按上面这个写法来就行。

记得测试一下各种网络状况下的表现,我之前就被无限重试坑过,调试起来可真够呛。
点赞
2026-03-27 21:12
Mr.巧梅
Mr.巧梅 Lv1
问题在于递归调用没有处理 resolve 情况。改用 async/await 和 for 循环更清晰。
const requestWithRetry = async (url, retries = 3) => {
for (let i = 0; i < retries; i++) {
try {
return await fetch(url);
} catch (err) {
if (i === retries - 1) throw err;
}
}
};
点赞
2026-03-22 19:02