我在用 fetch 做 API 请求,网络偶尔不稳定,想加个重试机制,但不知道怎么写才不乱。试过在 catch 里再调一次,结果有时候会无限重试,或者状态没控制好。
比如下面这个简单的请求组件,该怎么加最多重试三次的逻辑?
<script>
async function fetchData() {
const res = await fetch('/api/data');
if (!res.ok) throw new Error('请求失败');
return res.json();
}
</script>
用起来就是这样:
几个安全上的坑得提醒你:
不是所有请求都能随便重试。如果是 POST、PUT 这种会修改数据的请求,重试可能导致重复操作。比如用户付款,重试两次就付三次钱的事儿不是没发生过。解决办法是后端保证幂等性,或者前端生成个唯一请求 ID 让后端去重。
退避策略很重要。别傻傻地马上重试,网络抖动的时候你越重试越堵。上面的指数退避(1秒、2秒、4秒)是基础玩法,生产环境可以加随机抖动(jitter)避免多请求同时涌入。
4xx 错误别重试。客户端的请求有问题(比如 401 未认证、400 参数错误),重试一百万次也是白搭,反而可能把接口打挂。上面的代码已经帮你过滤掉了 400-499 的错误。
如果你的场景是用户登录这种关键操作,建议还是用专门的库比如 axios-retry 或者 workbox,边界情况处理得更完善。自己写的话上面这个够用,但记得根据实际业务调整策略。
调用的时候不用传参数,默认就试3次。试完还不行就抛出错误,外面再catch处理。