NgRx 与 switchMap 和 catchError 的效果 - 有人可以解释我的代码和“正确”代码之间可观察工作流程的差异吗?

Ida*_*buk 5 rxjs ngrx ngrx-effects angular switchmap

我发送了以下代码片段以供代码审查。此效果需要在请求调用后分派成功操作,或者如果服务方法抛出错误则分派错误操作,因此非常标准。

@Effect()
  fetchData$ = this.actions$.pipe(
      ofType(ActionTypes.FetchData),
      switchMap(() => {
        return this.dataService.fetchData().pipe(
            map((data: IData): StoreAction<IData> =>
                new FetchDataSuccess(data)),
            catchError((error) => of(addErrorValue(error, ErrorCode.FETCH_DATA)))
      )};
  ));
Run Code Online (Sandbox Code Playgroud)

然而,外部开发人员给了我一条评论(我没有与之联系,因此无法要求澄清)。他指示我用另一个 switchMap 包装我的 switchMap(就像下面的代码),因为我上面的代码中第一个 switchMap 内的捕获错误“会导致效果中断”。

@Effect()
  fetchData$ = this.actions$.pipe(
      switchMap((a: StoreAction<IType>) => of(a).pipe(
          ofType(ActionTypes.FetchData),
          switchMap(() => {
            return this.dataService.fetchData().pipe(
                map((data: IData): StoreAction<IData> =>
                    new FetchDataSuccess(data)),
            );
          }),
          catchError((error) => of(addErrorValue(error, ErrorCode.FETCH_DATA)))
      ))
  );
Run Code Online (Sandbox Code Playgroud)

现在,我阅读了有关捕获效果中的错误的内容,我的理解是 catchErrors 需要包装在 switchMap 中,因为这样效果就不会中断,因为失败的内部(而不是外部)可观察对象将被成功的可观察对象和效果可观察对象替换最终可以被迫进入成功状态(如果我理解正确的话)。

我不明白和缺少的是:为什么我们要将 switchMap 包装到另一个 switchMap 中?有人可以解释一下第一种情况与第二种情况下这个特定可观察量的工作流程吗?

tim*_*ver 9

这是无效的,第一个片段(您如何编写效果)是正确的。

你有一个catchError内部可观察的 ( this.dataService.fetchData) 就足够了。如果这里发生错误,它会被处理,catchError并且effect将调度action addErrorValue(error, ErrorCode.FETCH_DATA)

您可以在NgRx 示例应用程序中看到相同的模式

有关更多信息,请参阅https://blog.strongbrew.io/safe-http-calls-with-rxjs/https://medium.com/city-pantry/handling-errors-in-ngrx-effects-a95d918490d9