抛出错误后保持 Observable Stream 活动

Keeping Observable Stream Alive after Thrown Error

想知道如何在不终止流的情况下将错误从 observable 冒泡到订阅者的 err 函数

例如,进行 http 调用,当结果是 404 或任何其他错误时,我会捕获并在流中抛出错误。这会导致流终止并在 subscriber

中进入 err 函数块

但是,有没有办法捕获并保持流打开并将值传递给订阅者中的错误块。这是为了处理订阅者中的上述 404 错误,而不是流中的错误。用于执行错误处理和 UI 基于错误的更改。

更新代码: 我有这样的订阅者:

this.blahService.getSomething(id)
  .subscribe((response: Response) =>{

      this.cancelBtnText= 'Cancelled';
      this.canCancel = false;


    },
    err =>{
      console.log('ERRROR:::', err);
    });

主题如下:

return this.http.get(this.config.apiEndpointUrl, this.options)
  .map((r: Response) => <blah>r.json())
  .catch((error: any) => {
    console.error('A friendly error occurred', error);
    return Observable.throw(error.message || error);
  });

对于 http 错误,这将导致调用 catch 函数。但是,当我抛出错误时,这会终止流及其所有订阅者,因此下次事件来调用服务时,我的订阅者不再收听它并且完全取消订阅,因此,不会将任何信息发送回订阅。

当我在服务中将 throw 更改为 .empty() 时,这会发生变化,因为这不会终止流,但现在不再调用订户中的 error 函数。

我添加了这段代码来阐明订阅和错误处理的实际工作原理。

默认情况下,订阅(或管道)将保持完好无损地等待(侦听)您的下一个 http 请求,即使出现错误也是如此。

如果您将订阅分配给一个变量,您可以取消订阅.. 这是 NOT a recommended practice...

这个用例完全是假设的,但展示了如何通过代码停止订阅。

默认值 RxJS Subject 是另一种错误停止方式..

Subjects Are Not Reusable: In RxJS, Subjects cannot be reused. That is to say, when a Subject completes or errors, it can no longer be used. If you try to next on a Subject that is closed due to it’s complete or error method being called, it will silently ignore the notification. If you want the Subject to loudly and angrily error when you next to it after it’s done being useful, you can call unsubscribe directly on the subject instance itself.

import { Subscription } from "rxjs/Subscription";
...
export myComponent implements ngOnInit {
  sub: Subscription;
  records : DomainClz[];


  constructor(private domainService:DomainService) {}

  onInit() {
     // assumes getRecords returns Observable<DomainClz[]>
     // ie it chains map((resp:Response )to resp.json()) to http.get()
     this.sub = this.domainService.getRecords().
       subscribe(records => { this.records = records) },
                 error =>   { console.error(error)    }
       );
  }

  cancel() {
    this.sub.unsubscribe()
  }
}