即使捕获错误,Observable 也会停止触发

2024-01-24

我在我的项目中遇到了一个非常奇怪的行为,我有一个简单的 Angular 服务,代码如下:

seatClick$ = new Subject<Seat>();

以及服务上触发 observable 的方法:

  handleSeatClick(seat: Seat) {
    this.seatClick$.next(seat);
  }

可观察到的逻辑很简单:

this.seatClick$.pipe(
    exhaustMap((seat: Seat) => {
       this.someFunctionThatThrowsException(); // this function throws ref exception
      return of(null);
    })
    , catchError(err => {
        console.log('error handled');
        return of(null);
    })
)
.subscribe(() => {
    console.log('ok');
  },
  (error1 => {
    console.log('oops');
  })
);

这真的很奇怪,当调用“someFunctionThatThrowsException”时,它会抛出一些ReferenceError异常,然后用catchError捕获该异常并触发next()事件。

然而,从此时开始,seatClick observable 停止响应,就好像它已经完成一样,在服务上调用handleSeatClick 将不再响应。

我在这里缺少什么?


这是正确的行为,你需要repeat操作员在这里重新订阅。

this.seatClick$.pipe(
    exhaustMap((seat: Seat) => {
       this.someFunctionThatThrowsException();
       return of(null);
    })

    // in case of an error the stream has been completed.
    , catchError(err => {
        console.log('error handled');
        return of(null);
    })

    // now we need to resubscribe again
    , repeat() // <- here
)
.subscribe(() => {
    console.log('ok');
  },
  (error1 => {
    console.log('oops');
  })
);

另外,如果您知道某些事情可能会失败,您可以将其专用于内部流并使用catchError在那里,那么你不需要repeat.

this.seatClick$.pipe(
  // or exhaustMap, or mergeMap or any other stream changer.
  switchMap(seal => of(seal).pipe(
    exhaustMap((seat: Seat) => {
       this.someFunctionThatThrowsException();
       return of(null);
    })
    , catchError(err => {
        console.log('error handled');
        return of(null);
    })
  )),
  // now switchMap always succeeds with null despite an error happened inside
  // therefore we don't need `repeat` outside and our main stream
  // will be completed only when this.seatClick$ completes
  // or throws an error.
)
.subscribe(() => {
    console.log('ok');
  },
  (error1 => {
    console.log('oops');
  })
);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

即使捕获错误,Observable 也会停止触发 的相关文章

随机推荐