我有一个关于@ngrx效果的非常基本的问题:如何忽略在执行效果期间发生的错误,使其不影响将来的效果执行?
我的情况如下:我有一个动作(LOGIN)和一个听取该动作的效果 . 如果在此效果中发生错误,我想忽略它 . 在此错误后第二次调度LOGIN时,应该再次执行该效果 .
我第一次尝试这样做是:
@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,则没有任何反应;效果未执行 .
因此我尝试了以下方法:
.catch(err => {
return this.login$;
});
,但这导致无限循环......你知道如何捕获错误而不会阻止效果执行吗?
3 回答
发生错误时
@Effect
流正在完成,从而阻止任何进一步的操作 .解决方案是切换到一次性流 . 如果在一次性流中发生错误,则可以,因为主
@Effect
流始终保持活动状态,并且将来的操作将继续执行 .有关此技术的更多信息,请参阅此博客文章:The Quest for Meatballs: Continue RxJS Streams When Errors Occur
这就是我如何处理在没有找到任何数据的Observable上通知或不通知的选项:
ngrx
基础设施通过使用EffectsModule.run
导入应用程序NgModule
的提供程序订阅效果 .当可观察的错误和
catch
返回一个空的obervable时,组合的observable完成并且其订阅者被取消订阅 - 这是Observable Contract的一部分 . 这就是你认为没有进一步处理LOGIN
动作的原因 . 该效果在完成时取消订阅,ngrx
基础设施不会重新订阅 .通常,您将在
flatMap
(现在称为mergeMap
)内部进行错误处理:组成内部observable的
catch
将看到一个空的observable展平/合并到效果中,因此不会发出任何动作 .