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

redux-observable中concatMap用async fetch无法返回多action问题

问题原因

Redux Observable 中间件的核心逻辑是接收epic返回的动作流,将流中发射的每个单独值作为action分发给Redux。出现这个报错的核心原因是:

  1. 你在concatMap中使用了async函数,这类函数的返回值会被自动包装为Promise
  2. RxJS的concatMap处理Promise类型返回值时,只会将Promise resolve的最终结果作为单个值发射到流中,不会自动展开数组内的元素
  3. 你直接返回action数组时,整个数组会被当作单个"action"传给Redux,而Redux要求action必须是普通平面对象,数组不符合要求,因此抛出校验错误。

返回单个action时因为值本身就是符合要求的普通对象,所以可以正常运行。

修复方法

最简便的修复方式是使用RxJS内置的of操作符,将需要分发的多个action包装为会逐个发射值的Observable,concatMap会自动订阅这个Observable,把里面的每个action单独分发出去:

  1. 首先从rxjs导入of方法
  2. 原本返回单个action、返回数组的位置,都改为返回of(...待分发的action列表)

修正后的核心代码如下:

import { of } from 'rxjs';
import { fetchCharactersAction, setCharactersList, setError } from 'models/actions/characterActions';
import { ofType } from 'redux-observable';
import { concatMap, catchError } from 'rxjs/operators';

const fetchCharactersEpic = action$ =>
  action$.pipe(
    ofType(fetchCharactersAction.type),
    concatMap(async ({ payload: { name, status, gender, page } }) => {
      const url = `${process.env.REACT_APP_RICKANDMORTY}/character?page=${page}&name=${name}&status=${status}&gender=${gender}`;
      const characters = await fetch(url);
      const returnedCharacters = await characters.json();

      if (returnedCharacters?.error === '' || !returnedCharacters?.error) {
        // 多action直接作为of的参数传入即可,支持任意数量
        return of(
          setCharactersList(returnedCharacters),
          // 其他需要同步分发的action按顺序写在这里即可,比如action2(), action3()
        );
      }

      return of(setError(returnedCharacters?.error));
    }),
    // 建议补充错误捕获,避免请求异常时整个epic终止
    catchError(async (err) => of(setError(err.message)))
  );

如果不想使用of包装,也可以把async/await改写为Promise链式调用,在then中返回数组——但这种写法可读性更差,不推荐。

补充说明:如果concatMap的回调不是async函数、直接返回action数组,RxJS会自动将数组转为逐个发射元素的Observable,不会出现这个问题,但async函数返回Promise包裹数组的场景下不会触发这个自动转换逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 23:09:24