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

Redux Saga actionChannel文件上传动作串行执行失效问题排查

问题分析与修正方案

核心问题点

  1. fileUploadSaga 写法错误:直接返回包含yield的数组,未正确启动监听saga;rootSaga中错误地展开generator函数而非调用后的迭代器。
  2. Worker Saga 未接收Action参数:watchRequests中调用worker saga时,未传递当前action,导致API调用缺少action.payload。
  3. XSRF Token 未传递:未实现将前一次请求返回的token注入下一次请求的逻辑。

修正后的完整代码

1. 修正Saga核心逻辑

import { take, actionChannel, call, put } from 'redux-saga/effects';
import { AnyAction } from 'redux';
import { ServicesType } from '../services/types';
import { 
  uploadLossOfAccountMaleSuccess, 
  uploadLossOfAccountFemaleSuccess, 
  fetchDataFailure, 
  UploadExistingAccountMaleSuccess,  
  UploadExistingAccountFemaleSuccess
} from './actions';
import {
  UPLOAD_ACCOUNT_LOSS_REQUEST_MALE, 
  UPLOAD_ACCOUNT_LOSS_REQUEST_FEMALE, 
  UPLOAD_ACCOUNT_EXIST_REQUEST_MALE, 
  UPLOAD_ACCOUNT_EXIST_REQUEST_FEMALE
} from './actionTypes';

type Services = Pick<ServicesType, 'FileUpload'>;

// 存储最新的XSRF Token
let latestXSRFToken: string | undefined;

function uploadLossOfAccount(services: Services, gender: string) {
  return function* (action: AnyAction) {
    try {
      // 注入最新的XSRF Token到请求头
      const config = {
        headers: latestXSRFToken ? { 'X-XSRF-TOKEN': latestXSRFToken } : {}
      };
      const data = yield call(services.FileUpload.postData, action.payload, config);
      
      // 更新XSRF Token
      if (data.xsrfToken) {
        latestXSRFToken = data.xsrfToken;
      }

      gender === "male" 
        ? yield put(uploadLossOfAccountMaleSuccess(data)) 
        : yield put(uploadLossOfAccountFemaleSuccess(data));
    } catch (error) {
      yield put(fetchDataFailure((error as Error).message));
    }
  };
}

function UploadExistingAccount(services: Services, gender: string) {
  return function* (action: AnyAction) {
    try {
      // 注入最新的XSRF Token到请求头
      const config = {
        headers: latestXSRFToken ? { 'X-XSRF-TOKEN': latestXSRFToken } : {}
      };
      const data = yield call(services.FileUpload.postData, action.payload, config);
      
      // 更新XSRF Token
      if (data.xsrfToken) {
        latestXSRFToken = data.xsrfToken;
      }

      gender === "male" 
        ? yield put(UploadExistingAccountMaleSuccess(data)) 
        : yield put(UploadExistingAccountFemaleSuccess(data));
    } catch (error) {
      console.error('上传失败:', error);
    }
  };
}

function* watchRequests(services: Services) {
  const requestChannel = yield actionChannel([
    UPLOAD_ACCOUNT_LOSS_REQUEST_MALE, 
    UPLOAD_ACCOUNT_LOSS_REQUEST_FEMALE, 
    UPLOAD_ACCOUNT_EXIST_REQUEST_MALE, 
    UPLOAD_ACCOUNT_EXIST_REQUEST_FEMALE
  ]);

  while (true) {
    const action = yield take(requestChannel);
    // 关键:传递action给worker saga
    switch (action.type) {
      case UPLOAD_ACCOUNT_LOSS_REQUEST_MALE:
        yield call(uploadLossOfAccount(services, "male"), action);
        break;
      case UPLOAD_ACCOUNT_LOSS_REQUEST_FEMALE:
        yield call(uploadLossOfAccount(services, "female"), action);
        break;
      case UPLOAD_ACCOUNT_EXIST_REQUEST_MALE:
        yield call(UploadExistingAccount(services, "male"), action);
        break;
      case UPLOAD_ACCOUNT_EXIST_REQUEST_FEMALE:
        yield call(UploadExistingAccount(services, "female"), action);
        break;
    }
  }
}

export default function* fileUploadSaga(services: Services) {
  // 正确启动监听saga
  yield call(watchRequests, services);
}

2. 修正RootSaga

import { all } from 'redux-saga/effects';
import fileUploadSaga from './fileUploadSaga';
// 导入其他sagas
// import remainingSagas from './remainingSagas';

// 假设services在rootSaga中注入
import services from '../services';

export default function* rootSaga() {
  yield all([
    fileUploadSaga(services),
    // ...remainingSagas // 其他saga直接放入数组
  ]);
}

关键修正说明

  • 修复Saga启动逻辑:fileUploadSaga不再返回数组,直接调用watchRequests;rootSaga中正确传入services并启动saga,而非展开generator函数。
  • 传递Action参数:调用worker saga时,先执行uploadLossOfAccount(services, "male")获取generator,再传入action,确保worker能拿到action.payload。
  • XSRF Token 传递:新增全局变量存储最新token,每次请求前注入请求头,请求成功后更新token,保证串行请求的token连贯性。
  • 语法错误修复:修复了actions导入时的逗号缺失、fileUploadSaga中的括号错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:40:36