首页 > 解决方案 > 如果发生令牌刷新,则重新启动 API 请求队列

问题描述

我很难围绕我试图实现的这种模式来思考,所以我希望堆栈溢出社区能够帮助我解决这个问题。

目前我使用redux-thunkwithsuperagent来处理对我的 API 的调用并将其与 redux 同步

这方面的一个例子可能看起来像

export const getUser = (id) => {
  return (dispatch) => {
    const deferred = new Promise((resolve, reject) => {
      const call = () => {
        API.get(`/users/${id}`)
        .then((response) => response.body)
        .then((response) => {
          if (response.message === 'User found') {
            serializeUser(response.data).then((response) => {
              resolve(response);
            });
          } else {
            reject('not found');
          }
        }).catch((err) => {
          handleCatch(err, dispatch).then(call).catch(reject)
        });
      }
      call()
    });
    return deferred;
  };
};

在服务器返回 200 和一些数据的情况下,我继续将数据放入存储并呈现到页面或我的应用程序所做的任何事情。

在我收到错误的情况下,我尝试编写一个函数来拦截这些错误并确定它是否应该在页面上显示错误,或者在我们的 API 出现 401 的情况下,尝试刷新令牌,然后尝试调用该方法...

import { refreshToken } from '../actions/authentication';

export default (err, dispatch) => {
  const deferred = new Promise((resolve, reject) => {
    if (err.status === 401) {
      dispatch(refreshToken()).then(resolve).catch(reject)
    } else {
      reject(err);
    }
  })
  return deferred;
};

这可行,但是,我必须将其添加到每个调用中,并且它不考虑如果正在进行刷新则不应尝试调用的并发调用。

在我对这个主题的研究中,我看到了一些redux-saga可能可行的东西,但我无法思考如何使这项工作发挥作用

基本上,我需要一个队列之类的东西,我的所有 API 请求都将进入该队列,该队列可能会被去抖动,因此任何并发请求都将被推送到最后,一旦超时结束,调用就会堆积起来,当第一个调用得到 401 时暂停队列,直到令牌刷新成功,在这种情况下它会继续队列,或者失败,在这种情况下,它会取消队列中的所有未来请求并将用户发送回登录页面

我在这里担心的是如果堆栈中的第一个调用需要很长时间,我不希望其他调用必须等待很长时间,因为它会增加用户感知的加载时间

有没有更好的方法来处理保持令牌刷新?

标签: reduxjwtredux-thunkredux-sagarefresh-token

解决方案


推荐阅读