基于规则的Redux可观察史诗中的多个动作

时间:2018-07-18 21:27:15

标签: redux react-redux rxjs redux-observable

我意识到我可以在redux-observable epic中发出多个动作,并且已经看到了一些示例,但是我似乎无法正确解决这个问题。

基本上,我想返回三个互不依赖的动作。但是,每个操作都将基于我必须使用状态中的某些值做出的决定。所以,是这样的:

const doX = () => ({ type: types.DO_X });
const doY = () => ({ type: types.DO_Y });
const doZ = () => ({ type: types.DO_Z });
const doA = () => ({ type: types.DO_A });
const doB = () => ({ type: types.DO_B });
const doC = () => ({ type: types.DO_C });

export const myEpic = (action$, state$) => action$.pipe (
   ofType(types.SOMETHING_HAS_HAPPENED)
   mergeMap(action => Observable.of(
      const value1 = state$.value.module1.value;
      if(value1 > 10) {
          doX();
      } else {
          doY();
      },
      // Second action
      const value2 = state$.value.module2.value;
      if(value2) {
         doA();
      } else {
         doB();
      },
      // Third action -- similar idea here
   )
);

这是业务逻辑模块无法正常工作的地方。另外,我认为在这种情况下应该使用mergeMap,但不能100%确定。

在这种简单的情况下,我可以轻松完成if(state$.value.module1.value > 10),但是在我的应用程序中,由于要处理多个值,因此更容易将这些值分配给局部变量。因此,最好创建一个不错的代码块,在这里我可以清楚地列出业务逻辑。

我该如何处理?

2 个答案:

答案 0 :(得分:0)

您不必在mergeMap函数中使用箭头函数的 expression 版本。您可以将箭头功能与 body return语句一起使用以返回新的observable:

mergeMap(action => {

    const actionsToEmit = [];

    const value1 = state$.value.module1.value;
    if (value1 > 10) {
      actionsToEmit.push(actionCreatorX());
    } else {
      actionsToEmit.push(actionCreatorY());
    }

    // Second action
    const value2 = state$.value.module2.value;
    if (value2) {
      actionsToEmit.push(actionCreatorA());
    } else {
      actionsToEmit.push(actionCreatorB());
    }

    return Observable.of(...actionsToEmit);
  }
)

所以这只是标准的程序代码...

答案 1 :(得分:0)

const epic = (action$, state$) =>
    action$.pipe(
           ofType(SOME_TYPE)
           mergeMap(val => empty().pipe(
              merge(state$.value.v1 ? of(creatorA()) : empty())
              merge(state$.value.v2 ? of(creatorB()) : empty())
              merge(state$.value.v3 ? of(creatorC()) : empty())
              )
           )

如果我真的需要在一部史诗中分派少量动作,我会做这样的事情。您可以返回数组ofempty来代替[creator()][]。为了避免无限循环,我吞下了初始操作。但是,请考虑将其分为几个史诗。