NgRx 效果合并映射方法



我有两个具有相同效果的实现,并且都有效。我很难理解两者之间的差异以及哪个更"正确"。

请在下面找到它们:

选项 1.IDE 无法确定最近mapinstance的类型。

pollingStarted$ = createEffect(() =>
this.actions$.pipe(
ofType(pollingStarted),
mergeMap(action => action.instances),
map(instance => performRequest({ instance }))
)
);

选项 2.所有类型都可以工作并且有意义。这对我来说更正确,但我想弄清楚并理解其中的区别。

pollingStarted$ = createEffect(() =>
this.actions$.pipe(
ofType(pollingStarted),
mergeMap(({ instances }) =>
instances.map(instance => performRequest({ instance }))
)
)
);

这里有一个非常好的指南,介绍了好的和坏的做法。

考虑你的第二个例子。如果要在第二个地图中添加另一个地图,该怎么办?

pollingStarted$ = createEffect(() =>
this.actions$.pipe(
ofType(pollingStarted),
mergeMap(({ instances }) =>
instances.map(instance => performRequest({ 
instance.map(() => { // And another map})
}))
)
)
);

这很快就会使您的代码不可读。错误处理呢?

在第一个示例中,您可以只添加一个适用于所有地图的 catchError。在第二种情况下,您需要为那里的每张地图做一个错误手。

// VERY BAD: nesting subscribes is ugly and takes away
// the control over a stream

这同样适用于地图和任何其他应通过管道传输的运算符。管道运算符等效于 linux pipe|,被认为是最佳实践。它提供了更干净的代码。

对于其中的几个可能没有意义,但是当它嵌套在多个级别中时,它会变得非常讨厌并且代码变得不可读。

我最近进行了重构,使状态 2 看起来像一个大项目中的状态,这样我就可以更好地管理代码。

似乎第一种方法应该行不通:

pollingStarted$ = createEffect(() =>
this.actions$.pipe(
ofType(pollingStarted),
mergeMap(action => action.instances),
map(instance => performRequest({ instance }))
)
);

在这种情况下,mergeMap扁平化数组,map为每个发出的值返回一个 Observablve。最后,你会得到一个可观察量的可观察量(Observable<Observable<your type>>(。您需要使用其中一个高阶可观察量而不是map才能使其正常工作。

第二个选项是正确的:

pollingStarted$ = createEffect(() =>
this.actions$.pipe(
ofType(pollingStarted),
mergeMap(({ instances }) =>
instances.map(instance => performRequest({ instance }))
)
)
);

在这种情况下,mergeMapinstances.map生成的可观察量数组合并为单个可观察量。 使用此方法的好处是可以控制可观察量,可以将catchError应用于每个performRequest,或者在mergeMap后将其应用于更高级别,以便对所有performRequest调用进行单个错误处理。

最新更新