如何在行为主题上抛出错误并继续流?

新手上路,请多包涵

一方面,我有一个偶尔会抛出错误的流:

 this.behaviorSubject.error(error)

然而,稍后,我想继续直播:

 this.behaviorSubject.next(anotherValue)

在另一端,我有一个订阅者订阅了 behaviorSubject.asObservable()

在订阅中,我正在处理值和错误:

 .subscribe(
   ( value ) =>  {  /* ok */ },
   ( error ) =>  {  /* some error */ }
);

我希望效果与简单的 onSuccessonError 回调相同,其中 onError onSuccess 发生错误时都会调用,并且不会 --- 正在拨打电话。我如何使用 RXJS 执行此操作?

我已经研究了 catch,但它似乎只是防止错误被订阅者调用。

原文由 David 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 427
2 个回答

简短的回答: 这是不可能的。

如何处理: RxJS 的基本概念是任何 errorcomplete 调用基本上会 “杀死” 一个流。这个概念迫使您不能 “随心所欲地在这里和那里抛出错误” ,而是要正确处理应用程序中的错误和数据流。 A BehaviorSubject 例如通常用于保存数据,但它 应用于还包括检索/创建该数据的过程以及处理在检索数据期间可能发生的可能错误。

所以如果你想 _照章办事_,你应该 把你的流程分成两部分

  1. 数据的检索/创建:一个流,它将运行一次然后完成和/或在发生错误时抛出错误。当检索到数据时,它将被发送到商店。
  2. 商店(例如,在您的情况下:一堆 BehaviorSubjects):只有有效数据到达商店,这意味着这里没有进行任何错误处理,并且依赖商店的所有部分都可以信任商店,它拥有正确的数据。

例如,您的数据流可能如下所示(作为粗略草图):

商店.ts

 dataStore: BehaviorSubject<IData> = new BehaviorSubject<IData>();
errorMessage: BehaviorSubject<IErrorMsg> = new BehaviorSubject<IErrorMsg>();

数据检索.ts

 fetchDataById(id: string) {
    httpService.get(`some/rest/endpoint/${id}`)
        .subscribe(handleData, handleError);
}

handleData(data: IData) {
    errorMessage.next(null);
    dataStore.next(data);
}

handleError(error: Error) {
    errorMessage.next(error.message);
    dataStore.next(null);
}


“但这看起来开销很大……” - 没错,但它确保应用程序中的数据流干净且易于理解,易于测试和维护。也有现成的存储概念,如 ngrxredux 可以使用。

原文由 olsn 发布,翻译遵循 CC BY-SA 4.0 许可协议

Rx 从根本上建立在可观察对象处于活动状态或已完成(onComplete 或 onError)的概念之上。当一个 Observable 结束时,它将取消订阅它的上游 Observable。否 .catch 可以修复该行为,它只为您提供将错误映射到其他内容的选项。

 Rx.Observable.interval(500)
  .mergeMap(i => i % 3 == 2 ? Rx.Observable.throw(new Error('kboom')) : Rx.Observable.of(i))
  .catch(err => Rx.Observable.of(err.message))
  .subscribe(
    val => console.log('val: ' + val),
    err => console.log('err: ' + err),
    () => console.log('stream completed')
  )

请注意,此示例在 3 次发射而不是 5 次后完成

当您调用 this.behaviorSubject.error(error) 时,它将在内部完成包含在您的主题中的 Observable。如果你想以某种方式发出错误,那么你需要让你的错误成为非错误值:

 this.behaviorSubject.next({ value: 'somevalue' });
this.behaviorSubject.next({ error: error });
this.behaviorSubject.next({ value: 'somevalue' });

然后,您就可以根据发射值的属性来区分您应该采取什么行动。

原文由 Mark van Straten 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题