Vue中Ajax请求失败后如何实现自动重试?
最近在做数据上报功能时遇到问题,想给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”。哪里出问题了?重试逻辑该怎么改才正确?
setTimeout里又去调sendReport,但while循环还在继续,导致请求堆积,而且递归太深就爆栈了。关键点是:重试必须是顺序执行,不能用
while循环里套异步+setTimeout这种组合,得用递归但要控制好节奏,或者用async函数自己包一层循环。代码放这了,改完直接能用:
或者更稳一点,把
axios封装成带重试的实例,以后直接用:别用
while里套异步+setTimeout这种写法,容易把自己绕晕,也容易炸栈,用async/await递归或者封装一层更清晰。this.sendReport()上,每次失败都重新从头开始执行整个函数,相当于无限套娃,不爆栈才怪。而且setTimeout是异步的,根本不会等它执行完就继续循环了,retryCount 也完全没起作用。要实现重试机制,核心是:请求失败后等待一段时间再重试,不是立刻递归调用整个方法。下面是改好的代码,直接复制这个:
关键点:
- 用 for 循环控制重试次数,每次失败只重试当前请求
- 用
await new Promise + setTimeout实现真正的延迟等待- 不要再调自己,避免递归堆叠
这样就能做到失败后隔1秒重试,最多3次,不会重复发一堆请求。