Vue中Ajax请求失败后如何实现自动重试?

Dev · 星宇 阅读 26

最近在做数据上报功能时遇到问题,想给axios请求加重试机制。比如网络波动时自动重试3次,但试了setTimeout递归调用,发现每次重试都同时发送了请求,反而更卡了…

这是我的代码片段:

<script>
methods: {
  async sendReport() {
    let retryCount = 0;
    while(retryCount < 3) {
      try {
        await axios.post('/api/report', this.data);
        break;
      } catch(err) {
        setTimeout(() => this.sendReport(), 1000);
        retryCount++;
      }
    }
  }
}
</script>

可是发现第一次失败后会同时触发多次请求,控制台提示”Maximum call stack size exceeded”。哪里出问题了?重试逻辑该怎么改才正确?

我来解答 赞 7 收藏
二维码
手机扫码查看
1 条解答
Good“令敏
你这问题出在递归调用 this.sendReport() 上,每次失败都重新从头开始执行整个函数,相当于无限套娃,不爆栈才怪。而且 setTimeout 是异步的,根本不会等它执行完就继续循环了,retryCount 也完全没起作用。

要实现重试机制,核心是:请求失败后等待一段时间再重试,不是立刻递归调用整个方法。下面是改好的代码,直接复制这个:

async sendReport() {
const maxRetries = 3;
for (let i = 0; i < maxRetries; i++) {
try {
await axios.post('/api/report', this.data);
return; // 成功就退出
} catch (err) {
if (i === maxRetries - 1) throw err; // 最后一次失败再抛错
await new Promise(resolve => setTimeout(resolve, 1000)); // 等1秒再重试
}
}
}


关键点:
- 用 for 循环控制重试次数,每次失败只重试当前请求
- 用 await new Promise + setTimeout 实现真正的延迟等待
- 不要再调自己,避免递归堆叠

这样就能做到失败后隔1秒重试,最多3次,不会重复发一堆请求。
点赞 2
2026-02-09 19:03