3

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

@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(就像下面的代码一样),因为在我上面的代码中的第一个 switchMap 中的 catch 错误“会导致效果中断”。

@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 中,因为这样效果就不会中断,因为失败的内部(而不是外部)observable 将被成功替换并且效果 observable最终可以被迫进入成功状态(如果我理解正确的话)。

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

4

1 回答 1

5

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

catchError在内部可观察对象 ( this.dataService.fetchData) 上有一个就足够了。如果这里发生错误,它会被处理catchError并且效果会派发 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

于 2019-11-14T12:24:14.447 回答