即使捕捉到错误,Observable 也会停止触发 [英] Observable stops firing even when catching the error

查看:72
本文介绍了即使捕捉到错误,Observable 也会停止触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm facing with a very strange behavior on my project, I have a simple Angular service with the below code:

seatClick$ = new Subject<Seat>();

以及触发 observable 的服务方法:

and a method on the service that fires the 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()事件.

This is really strange, when "someFunctionThatThrowsException" is called it throws some ReferenceError exception, this exception is then catched with the catchError and the next() event is fired.

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

However, from this moment on the seatClick observable stops responding, as if it was completed, calling handleSeatClick on the service won't respond any more.

我在这里遗漏了什么?

推荐答案

这是正确的行为,您需要 repeat 运算符在这里重新订阅.

That's correct behavior, you need repeat operator here to resubscribe.

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.

also if you know that something might fail you can dedicate it to an internal stream and use catchError there, then you don't need 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');
  })
);

这篇关于即使捕捉到错误,Observable 也会停止触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆