简体   繁体   English

rxjs错误处理>在catchError源上停止发出

[英]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的简单示例:

(live demo here ) 这里有现场演示)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM