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

如何在redux-saga中使用yield解决token存储时序异常问题

问题根因

你遇到的问题由两个错误用法导致:

  1. redux-saga 中 put 方法是非阻塞的,你在捕获到jwt过期后连续触发 REFRESH_REQUEST 和 GETPOST_REQUEST 两个action,refresh 逻辑还没执行完,新的getPost请求已经发起,自然拿不到更新后的token
  2. 你直接 yield AsyncStorage.setItem 没有用 call 包装,saga不会等待这个异步存储操作执行完成,就会提前触发 REFRESH_SUCCESS 动作

解决步骤

1. 改造refresh saga,确保token存储完成后再结束流程

将异步存储操作用saga的call方法包装,阻塞saga执行直到token写入AsyncStorage完成:

function* refresh() {
  try {
    const result = yield call(refreshAPI);
    // 用call包装异步方法,saga会等待存储完成再往下执行
    yield call(AsyncStorage.setItem, 'accesstoken', `${result.data.accessToken}`);
    // 可选:如果你的refreshToken也会更新,这里同步存储refreshToken
    yield put({
      type: REFRESH_SUCCESS,
      data: result.data,
    });
  } catch (err) {
    yield put({
      type: REFRESH_FAILURE,
      error: err.response.data,
    });
  }
}

2. 改造getPost的异常处理逻辑,等待refresh流程完全结束后再重发请求

用saga的take方法监听refresh的结束动作,确保refresh跑完再发起新的业务请求:

function* getPost(action) {
  try {
    const result = yield call(getPostAPI, action.data);
    yield put({
      type: GETPOST_SUCCESS,
      data: result.data,
    });
  } catch (err) {
    if (err.response.data === 'jwtEx') {
      yield put({
        type: REFRESH_REQUEST,
      });
      // 阻塞等待refresh流程结束(成功/失败都要等)
      const refreshAction = yield take([REFRESH_SUCCESS, REFRESH_FAILURE]);
      // 只有refresh成功才重发请求,失败的话可以按业务逻辑处理登出/提示
      if (refreshAction.type === REFRESH_SUCCESS) {
        yield put({
          type: GETPOST_REQUEST,
          data: action.data,
        });
      } else {
        // 这里可以加refresh失败的处理,比如清空存储跳转到登录页
        yield put({
          type: GETPOST_FAILURE,
          error: '登录状态已过期,请重新登录',
        });
      }
    } else {
      yield put({
        type: GETPOST_FAILURE,
        error: err.response.data,
      });
    }
  }
}

补充说明

你现有axios.js的拦截器逻辑不需要修改,只要保证请求发起时token已经写入AsyncStorage,拦截器就能读到最新的token值附加到请求头。

内容的提问来源于stack exchange,提问作者jack volten

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 07:54:03