uni.request重试必须手动封装,官方不提供retry参数;需按错误类型判断是否重试,对timeout、502/503/504等适合重试,401应刷新token,400/404等客户端错误不可重试;App端须用指数退避且限制次数,同时防重复请求与状态污染。

uni.request 重试必须自己封装,官方不提供 retry 参数
uni.request 没有 retry、retries 或 shouldRetry 这类原生配置项。所有重试逻辑必须手动实现——靠 Promise 链、递归调用或 while 循环控制,不能寄希望于加个字段就自动重发。
重试前必须判断错误类型,不是所有失败都该重试
直接对所有 fail 回调无差别重试,轻则浪费流量,重则触发风控(比如连续三次 401 登录失败导致账号锁定)。关键看错误来源:
-
err.errMsg === 'request:fail timeout':弱网超时,适合重试 -
err.errMsg.includes('Network Error'):断网或 DNS 失败,可重试 -
res.statusCode是502/503/504:服务端临时不可用,建议重试 -
res.statusCode === 401:token 过期,应刷新 token 而非重试请求 -
res.statusCode === 400或404:客户端问题,重试无意义
App 端重试要加退避策略,别连发
在 iOS/Android 上连续发起相同请求,既没效果又可能被系统限流。推荐指数退避(exponential backoff):
- 第 1 次失败后等
300ms再试 - 第 2 次失败后等
900ms(300 × 3) - 最多重试
2次(含首次),避免用户卡在 loading 里太久 - 重试时需保留原始
options,但覆盖timeout(比如从 8s 提到 12s)
重试过程必须防重复提交和状态污染
用户快速点击两次「提交」,若没锁住,可能发出去两个请求 + 各自重试 2 次,共 6 次调用。实际要:
- 用
Symbol或时间戳生成唯一requestId,记录在 Map 中 - 重试前查该
requestId是否已在进行中,是则直接返回已有 Promise - 成功或最终失败后,务必从 Map 中清除该 ID
- 不要在重试函数里调
uni.showToast,提示应由业务层统一控制,否则会弹多次


















