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

2023-11-21

我对 rxjs 有点困惑catchError操作员。这是一个使用 Angular 的简单示例:

(现场演示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 发出 0,1,2,然后发出错误。该错误被捕获在catchError运算符默默地吞下错误并发出 42。我想我明白这一点。然而,发射随后停止(我期待 4、5、6,...)。有人可以解释为什么这种情况不会发生以及是否有任何方法可以实现这种行为?

这在实践中对我来说很重要,在如下情况下,我们每次发出路由参数时都会加载新数据。假设我们导航到引发错误的路线(例如 404、500,...),我不希望事件流停止发出,因为这样我就无法导航回任何其他页面。我只想优雅地处理错误并继续侦听路线更改。

this.foo$ = this._route.params.pipe(
  map(params => params.id),
  switchMap(id => this._fooServerClient.getOneById(id)),
  catchError(err => {
    return of(undefined)
  })
)

这是 Observable 的设计初衷,如果 Observable 管道中发生异常,相应的 observable [引发错误] 将处于错误状态,并且无法发出新的/进一步的值 [即就像取消订阅一样]。

现在,为了让你的外部可观察的保持活跃[即。继续发出新值]然后处理内部可观察的错误[即使用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在内部可观察管道中将使外部可观察保持活动状态[即即使内部可观察抛出异常,也要继续发出新值]。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

rxjs 错误处理 > catchError 源停止发出 的相关文章

随机推荐