如何针对 401 错误的多个请求运行 axios 拦截器一次?

Dev*_*han 2 javascript frontend promise reactjs axios

我已经为我的食品应用程序设置了 axios 和 react-query 。我只想为 2 个以上的并行请求实现一次刷新令牌,并重试所有挂起的失败请求。我在网上搜索了很多解决方案,尝试了它们,但没有一个起作用。这是我的代码参考。

let isRefreshing = false;
let failedQueue = [];

async function refreshToken() {
  const response = await normalRoute.post("/users/refresh");
  return response.data.accessToken;
}

privateRoute.interceptors.response.use(
  (response) => response,
  async (error) => {
    if (error.response.status === 401) {
      failedQueue.push(error.config);
      if (!isRefreshing) {
        isRefreshing = true;
        const token = await refreshToken();
        store.dispatch(setAccessToken(token));

        const promsieArray = failedQueue.map((config) => {
          config.headers.authorization = `Bearer ${token}`;
          return privateRoute(config);
        });

        failedQueue = [];
        return Promise.resolve(promsieArray);
      }
    }
  }
);
Run Code Online (Sandbox Code Playgroud)

Tho*_*mas 9

我认为你的解决方案有点太复杂了。我只是存储返回的 Promise,refreshToken()直到它完成为止,并让所有传入的401Promise 等待相同的 Promise,然后重试。

let refreshPromise = null;
const clearPromise = () => refreshPromise = null;

async function refreshToken() {
  const response = await normalRoute.post("/users/refresh");
  return response.data.accessToken;
}

privateRoute.interceptors.response.use(
  undefined,
  async (error) => {
    const config = error.config;
    
    if (error.response.status === 401 && !config._retry) {
      config._retry = true;

      if (!refreshPromise) {
        refreshPromise = refreshToken().finally(clearPromise);
      }

      const token = await refreshPromise;
      config.headers.authorization = `Bearer ${token}`;

      return privateRoute(config);
    }
  }
);

Run Code Online (Sandbox Code Playgroud)

并在 Promise 完成时将其杀死,以便稍后401有机会再次刷新令牌。