You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中箭头函数自调用处理401重试请求出现死循环如何解决

死循环原因

两个核心问题:

  • 无递归终止条件:只要接口持续返回401,递归就不会停止。常见触发场景是401分支的token刷新逻辑没有等待执行完成就发起重试,或是刷新后的新token没有正确注入请求头,导致每次重试都携带旧token,持续触发401响应。
  • Promise链断裂:401分支内如果不return递归调用的tokenGet,外层调用方的.then回调拿不到重试成功的返回值;如果加了return但没做终止判断,就会直接触发无限递归。
修复方案

首先给递归加上最大重试次数兜底,保证逻辑异常时也不会无限发请求;其次确保401处理逻辑执行完成后再发起重试,同时正确透传Promise链。

// 最大重试次数,根据业务需求调整,设1次就够覆盖常规token刷新场景
const MAX_RETRY = 1;

const tokenGet = async (url, retryCount = 0) => {
  // 注意:请求配置里的鉴权头不要拿闭包缓存的旧token,每次请求实时从存储里取最新值
  const requestConfig = {
    // 原有请求参数
    headers: {
      Authorization: `Bearer ${window.localStorage.getItem('access_token') ?? ''}`
    }
  };

  const res = await fetch(url, requestConfig);
  if (res.status === 401) {
    // 超过重试次数直接抛错终止
    if (retryCount >= MAX_RETRY) {
      throw new Error('鉴权已失效,请重新登录');
    }
    // 执行你原有的401处理逻辑:比如刷新token、清理无效状态等,一定要加await等执行完成
    await handle401Logic();
    // 重试时计数+1,必须return,把Promise结果透传给外层调用方
    return tokenGet(url, retryCount + 1);
  }
  return res.json();
};

组件内调用部分补上错误捕获即可:

useEffect(() => {
  tokenGet(url)
    .then(data => {
      // 处理正常返回的业务数据
    })
    .catch(err => {
      // 处理请求失败、重试耗尽的场景,比如跳转登录页
      console.error('请求异常', err);
    });
}, []);
关键注意事项
  • 不要把token存在tokenGet函数作用域的常量里缓存,否则刷新token后函数内拿到的永远是旧值,重试必然持续401触发死循环。
  • 401分支的token刷新等异步逻辑必须加await等待执行完成,再发起重试请求,否则重试时新token还未写入存储,还是会返回401。
  • 必须保留最大重试次数的兜底逻辑,避免代码疏漏导致无限请求打垮服务或卡死页面。

内容的提问来源于stack exchange,提问作者Rafael Caixeta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:48:16