NgRx 对 switchMap 和 catchError 的影响 - 有人可以解释我的代码和 'correct' 代码之间可观察到的工作流程的区别吗?

NgRx effect with switchMap and catchError - can someone explain the difference in observable workflows between my code and the 'correct' one?

我将以下代码片段发送给代码审查。这个效果需要在请求调用后派发一个成功动作,或者如果服务方法抛出错误则派发一​​个错误动作,非常标准。

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

但是,我收到了一位外部开发人员的评论(我没有联系,因此无法要求澄清)。他指示我用另一个 switchMap 包裹我的 switchMap(就像我下面的代码),因为在我上面的代码 'would cause the effect to break' 中的第一个 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)))
      ))
  );

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

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

无效,第一个片段(您编写效果的方式)是正确的。

您在内部可观察对象 (this.dataService.fetchData) 上有一个 catchError,这就足够了。如果此处发生错误,则由 catchError 处理,效果将调度操作 addErrorValue(error, ErrorCode.FETCH_DATA).

您可以在 NgRx example app

中看到相同的模式

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