ngrx 效果错误处理 [英] ngrx effects error handling
问题描述
我有一个关于@ngrx 效果的非常基本的问题:如何忽略在效果执行期间发生的错误,使其不影响以后的效果执行?
I have a very basic question concerning @ngrx effects: How to ignore an error that happens during the execution of an effect such that it doesn't affect future effect execution?
我的情况如下:我有一个动作(LOGIN)和一个听那个动作的效果.如果此效果中发生错误,我想忽略它.在此错误后第二次调度 LOGIN 时,应第二次执行效果.
My situation is as follows: I have an action (LOGIN) and an effect listening to that action. If an error happens inside this effect, I want to ignore it. When LOGIN is dispatched a second time after this error, the effect should be executed a second time.
我第一次尝试这样做是:
My first attempt to do this was:
@Effect()
login$ = this.actions$
.ofType('LOGIN')
.flatMap(async () => {
console.debug('LOGIN');
// throw an error
let x = [];x[0]();
})
.catch(err => {
console.error('Error at login', err);
return Observable.empty();
});
按预期,第一次调度 LOGIN 会抛出并捕获错误.但是,如果我之后第二次发送 LOGIN,则什么也不会发生;效果不执行.
Dispatching LOGIN the first time throws and catches the error, as expected. However, if I dispatch LOGIN a second time afterwards, nothing happens; the effect is not executed.
因此我尝试了以下操作:
Therefore I tried the following:
.catch(err => {
return this.login$;
});
,但这会导致无限循环......你知道如何在不阻止效果执行的情况下捕获错误吗?
, but this results in an endless loop... Do you know how to catch the error without preventing effect execution afterwards?
推荐答案
ngrx
基础结构通过使用 EffectsModule.run
导入到应用程序的 NgModule
中的提供程序订阅效果.
The ngrx
infrastructure subscribes to the effect via the provider imported into the app's NgModule
using EffectsModule.run
.
当 observable 错误和 catch
返回一个空的 observable 时,组合的 observable 完成并且它的订阅者被取消订阅 - 这是 可观察的合约.这就是您在效果中看不到对 LOGIN
操作进行进一步处理的原因.该效果在完成时取消订阅,ngrx
基础结构不会重新订阅.
When the observable errors and catch
returns a empty obervable, the composed observable completes and its subscribers are unsubscribed - that's part of the Observable Contract. And that's the reason you see no further handling of LOGIN
actions in your effect. The effect is unsubscribed on completion and the ngrx
infrastructure does not re-subscribe.
通常,您会在 flatMap
(现在称为 mergeMap
)中进行错误处理:
Typically, you would have the error handling inside the flatMap
(now called mergeMap
):
import { Actions, Effect, toPayload } from "@ngrx/effects";
@Effect()
login$ = this.actions$
.ofType('LOGIN')
.map(toPayload)
.flatMap(payload => Observable
.from(Promise.reject('Boom!'))
.catch(error => {
console.error('Error at login', error);
return Observable.empty();
})
});
组成内部 observable 的 catch
将看到一个空的 observable 被压平/合并到效果中,因此不会发出任何动作.
The catch
composed into the inner observable will see an empty observable flattened/merged into the effect, so no action will be emitted.
这篇关于ngrx 效果错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!