React接口请求重试3次时状态闪烁问题该如何优化?
问题根因
- 递归调用
fetchAPIResource后未加return终止当前函数后续逻辑,上一轮请求的判断代码会在重试请求等待/执行期间继续运行,导致未等最后一次重试结果返回就提前命中失败条件 - 重试计数更新时机错误:先发起重试再更新计数,计数状态和实际重试次数不匹配
- 204状态的重试没有计入总重试次数,存在无限重试风险
- 异步逻辑混用
async/await和.then()链式调用,提升了时序控制的难度
优化后实现代码
const timeout = delay => { return new Promise(resolve => setTimeout(resolve, delay)) } const fetchAPIResource = useCallback(async () => { // 配置最多重试3次,总计发起4次请求 const MAX_RETRY_TIMES = 3 try { for (let retryCount = 0; retryCount <= MAX_RETRY_TIMES; retryCount++) { const res = await getStatus(transactionID) // 命中成功条件直接终止整个流程 if (res?.data?.receipt_is_settled) { setStatus('accepted') setShow(false) return } // 满足重试条件时等待5秒后进入下一轮重试 if ((res?.status === 204 || !res?.data?.receipt_is_settled) && retryCount < MAX_RETRY_TIMES) { await timeout(5000) } } // 所有重试结束仍未满足成功条件,走失败逻辑 setStatus('declined') setShow(false) } catch (error) { toast.error(error?.errors?.description || error?.description) setStatus('declined') } }, [transactionID])
核心优化说明
- 替换递归逻辑为
for循环控制重试次数,逻辑结构更清晰,完全避免时序错位问题 - 所有场景的重试统一计入总次数,不会出现超次数请求、无限重试的问题
- 优先判断成功条件,命中后直接返回终止流程,不会执行后续的失败状态更新逻辑
- 统一使用
async/await处理异步逻辑,移除冗余的.then()嵌套,时序控制更精准 - 补充
transactionID到useCallback依赖数组,避免闭包缓存旧参数导致的请求错误
内容的提问来源于stack exchange,提问作者Osong Agberndifor
相关产品推荐
相关产品推荐

