[英]rxjs error handling > on catchError source stops emitting
I'm a bit confused by the rxjs catchError
operator. 我对rxjs
catchError
运算符有点困惑。 Here is a simple example using Angular: 这是一个使用Angular的简单示例:
import { Component } from '@angular/core';
import { of, timer } from 'rxjs'
import { tap, catchError } from 'rxjs/operators'
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
})
export class AppComponent {
constructor() {
const source$ = timer(1000, 1000).pipe(tap(n => {
if (n === 3) {
throw new Error('n === 3')
}
}))
this.value$ = source$.pipe(catchError(err => {
return of(42)
}))
}
value$
}
{{ value$ | async }}
The source$
observable to which the async pipe subscribes emits 0,1,2 and then errors. 异步管道订阅到的
source$
可观察到的发出0,1,2,然后出现错误。 This error is caught in the catchError
operator which swallows the error silently and emits 42. This I think I understand. 这个错误在
catchError
运算符中捕获,该catchError
符将错误地吞下并发出42。我想我明白。 However, the emission then stops (I was expecting 4,5,6,...). 但是,发射随后停止了(我原以为是4,5,6,...)。 Can someone please explain why this does not occur and if there is any way of achieving such a behaviour?
有人可以解释为什么这种情况不会发生,以及是否有任何方法可以实现这种行为吗?
This matters to me in practice in a situation such as below, where we load fresh data every time the route params emit. 在以下情况下,这在实践中对我很重要,在这种情况下,每次发出路线参数时我们都会加载新数据。 Supposing we navigate to a route that throws an error (eg 404, 500,...) I do not want the event stream to stop emitting as then I am left unable to navigate back to any other page.
假设我们导航到引发错误的路线(例如404、500等),我不希望事件流停止发出,因为那样我就无法导航回任何其他页面。 I just want to handle the error gracefully and keep listening for route changes.
我只想优雅地处理错误并继续侦听路由更改。
this.foo$ = this._route.params.pipe(
map(params => params.id),
switchMap(id => this._fooServerClient.getOneById(id)),
catchError(err => {
return of(undefined)
})
)
It is by design of Observable if an exception occurs in an Observable pipeline, the respective observable [which throws an error] will be in error state and it cannot emit new/further value [ie it is like unsubscribe]. 如果Observable管道中发生异常,则是根据Observable的设计,相应的Observable [引发错误]将处于错误状态,并且无法发出新的/进一步的值[即,就像取消订阅一样]。
Now, to keep your outer observable live [ie keep emitting the new values] then handle the error in inner observable [ie use the catchError
operator in inner observable pipeline like this: 现在,要保持外部可观察的活动(即继续发出新值),然后处理内部可观察的错误[即在内部可观察的管道中使用
catchError
运算符,如下所示:
this.foo$ = this._route.params
.pipe(
map(params => params.id),
switchMap(id => {
return this._fooServerClient.getOneById(id)
.pipe(
catchError(err => {
return of(undefined);
})
)
}),
);
Having catchError
in the inner observable pipeline will keep outer observable live [ie keep emitting the new value even if inner observable throws exception]. 内部可观察管道中具有
catchError
将保持外部可观察活动(即即使内部可观察抛出异常,也继续发出新值)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.