4

我有两个相同效果的实现,并且都有效。我很难理解两者之间的区别,哪个更“正确”。

请在下面找到它们:

选项 1. IDE 无法确定instance最后一个map.

    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 }))
            )
        )
    );
4

2 回答 2

2

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

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

   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 管道 |,被认为是最佳实践。它提供了更简洁的代码。

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

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

于 2019-11-22T16:04:20.907 回答
1

似乎第一种方法不应该起作用:

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

mergeMap在这种情况下,您的数组会变平,并map为每个发出的值返回一个 Observablve。最后你会得到一个 Observable 的 Observable ( Observable<Observable<your type>>)。您需要使用更高阶的 Observable之一,而不是map让它工作。

第二个选项是正确的:

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

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

于 2019-11-29T11:36:35.090 回答