【问题标题】:Why action doesn't trigger Effect the second time it runs?为什么动作在第二次运行时不会触发效果?
【发布时间】:2019-03-12 00:42:14
【问题描述】:
效果:
@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,observable 已完成并且不会在我第二次调度操作时触发效果。我寻找一种方法来正确处理错误并继续可观察的流,以便我可以在我的组件中订阅它并采取相应的行动。
@ngrx Effect does not run the second time 中的解决方案对我不起作用,或者我无法使其起作用。
【问题讨论】:
标签:
angular
rxjs
observable
ngrx
ngrx-effects
【解决方案1】:
您需要catchError,而不是actions$。为此,您需要修改代码如下:
mergeMap(action =>
this.myService.getDocs().pipe(
map(data => new LoadDocsSuccess(data)),
catchError(error => Observable.of(new LoadDocsFailure(error)))
)
)
【解决方案2】:
我向您保证,这是正确的做法。我怎么知道?在 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 逻辑,但你明白了。