为什么 action 第二次运行时不触发 Effect?

Why action doesn't trigger Effect the second time it runs?

Effect:

@Effect()
  loadDocsEffect$ = this.actions$.pipe(
    ofType(myActionTypes.LoadDocs),
    mergeMap(action => this.myService.getDocs()),
    map(data => new LoadDocsSuccess(data)),
    catchError(error => Observable.of(new LoadDocsFailure(error)))
  );

它在我返回数据时有效,但当服务器响应错误时(例如 404),可观察对象已完成并且在我第二次分派操作时不会触发效果。我寻找一种方法来正确处理错误并继续观察流,以便我可以在我的组件中订阅它并采取相应的行动。

中的解决方案对我不起作用,或者我无法使它起作用。

您需要根据要求 catchError 而不是 actions$。为此,您需要按以下方式修改代码:

mergeMap(action => 
  this.myService.getDocs().pipe(
    map(data => new LoadDocsSuccess(data)),
    catchError(error => Observable.of(new LoadDocsFailure(error)))
  )
)

我向你保证这是正确的方法。我怎么知道?在 ngrx Udemy 课程上对这个确切问题进行了长时间的讨论,这就是他们提供的解决方案。请注意,使用 catchError 是必不可少的,否则 HTTP 错误响应(任何非 2xx 响应)将禁用此效果。

@Effect()
  loadDocsEffect$ = this.actions$.pipe(
    ofType(myActionTypes.LoadDocs),
    mergeMap((action) => {
      // essential to catchError else an HTTP error response will disable this effect
      return this.myService.getDocs().pipe(
        map(data => new LoadDocsSuccess(data)),
        catchError((err) => {
          return of(null)
        })
      )
    }),
    tap(res => console.log(res)) // you won't want this line but useful for debugging
  );

在此示例中,如果 HTTP 请求成功,new LoadDocsSuccess(data) 的结果将记录在 tap 中。如果 HTTP 请求失败,null 将被记录在 tap 中。当然,您可能想提供一些不同的 catchError 逻辑,但您明白了。