如何在 ngrx/effect 中调度多个操作(redux-observable)?



我正在使用Angular 6,ngrx/store。我有这样的效果,负责更新东西。取决于一些逻辑,我想调度不同的操作。如果我使用switchMap而不是map有什么区别?

这是我尝试过的,但它不起作用:

@Effect()
dispathMultipleActions$ = this.actions$.pipe(
ofType(ActionTypes.UpdateSomething),
map(() => {
const actions: Action[] = [];
const array = [1, 2, 3, 4, 5];
array.forEach(item => {
if (item > 3) {
actions.push(new DeleteAction(item));
} else {
actions.push(new ChangeAction(item));
}
});
return actions;
})
);

效果转换操作流,因此您将操作流作为输入和输出。在您的示例中,您将操作映射到操作数组。操作数组流不是有效的输出类型。您需要平展该数组,这意味着您不会将数组本身发射到输出流中,而是将其每个元素发射到输出流中。

而不是:

input:  --a-------a------>
output: --[b,c]---[b,c]-->

你应该做:

input:  --a-------a------>
output: --b-c-----b-c-->

要将数组的可观察量展平为每个元素的可观察量,可以使用运算符之一mergeMapswitchMapexhaustMap。在大多数情况下,mergeMap将是正确的选择。如果您想了解有关这些运算符的更多信息,请查看此答案。

@Effect()
register$: Observable<Action> = this.actions$.pipe(
ofType(AuthActionTypes.REGISTER_REQUEST),
mergeMap((action: RegisterRequest) => {
// check for register request success
return [
new RegisterSuccess(),
new LoginRequest(action.payload)
]
})
);

我遇到过同样的情况(假设 NgRx 10 或更高(,我有不同的观点,更基本的方式来使用效果。在一个地方按顺序触发多个动作,特别是在单个效果中,是反模式的。 从某种意义上说,在 NgRx 中保持一致的应用程序状态的一般流程和潜在的减少非常重要。正如NgRx架构所预见的那样。

遵循 3 条效果规则将有助于避免困难情况:

  1. 将效果命名为效果的名称
  2. 让你的效果只做一件事
  3. 仅发出一个操作

这样,它可以帮助您遵循关注点分离设计模式,这当然也可以帮助您将NgRx效果变得更加可测试。

回到您的示例,您可以使用中间代理操作简单地分离您想要执行的操作(2 个附加操作(。

在您的情况下,似乎您甚至不需要原始效果dispathMultipleActions$,除非其中出现特殊逻辑。(也许,可能属于状态化简器,它更易于单元测试(。

假设 ActionTypes.UpdateSomething 已经有一个数组有效负载对象,您可以将dispathMultipleActions$拆分为单个对象,因此您可以执行以下操作:

@Effect()
deleteAction$ = this.actions$.pipe(
ofType(ActionTypes.UpdateSomething),
concatMap(from(new Promise((array) => {
array.forEach(item => {
if (item > 3) {
//do something
}
});
}))),
{dispatch: false}
);
@Effect()
changeAction$ = this.actions$.pipe(
ofType(ActionTypes.UpdateSomething),
concatMap(from(new Promise((array) => {
array.forEach(item => {
if (item <= 3) {
//do something
}
});
}))),
{dispatch: false}
);

最新更新