为什么Rxjs会在出错时取消订阅?

时间:2017-08-03 06:52:51

标签: rxjs rxjs5

简而言之: 如何在流中出现错误后继续收听,而不是在.catch之前放置.subscribe

如果您需要更多详细信息,请访问:

让我们假设我有一个当前用户的主题或null。我有时从API获取数据并发送给主题。它相应地更新视图。   但是在某些时候我的服务器上发生了错误,我希望我的应用程序像以前一样继续工作,但是通知一些地方有关错误并保持听我的主题。

最初,我认为如果我只做userSubject.error(...),它只会在订阅时触发.catch回调和error处理程序,并跳过所有成功处理程序和链。   如果在我致电userSubject.next(...)后,我所有的连锁店和订户都将像以前一样工作

但不幸的是情况并非如此。在第一个未被捕获的.error之后,它取消订阅流中的订阅者,并且它们不再运行。

所以我的问题:为什么??? 如果我想正常处理null值而且只在某些地方处理错误,该怎么办?

以下是RxJs源代码的链接,其中Subscriber取消订阅错误 https://github.com/ReactiveX/rxjs/blob/master/src/Subscriber.ts#L140

2 个答案:

答案 0 :(得分:9)

Rx可观察量follow the grammar next*(error|complete)?,意味着在errorcomplete通知发出后,他们无法生成任何内容。

可以从Rx design guidelines找到有关其重要性的解释:

  

指示可观察序列已完成的单个消息确保可观察序列的使用者可以确定性地确定执行清理操作是安全的。

     

单个故障进一步确保可以为处理多个可观察序列的运算符维护中止语义。

简而言之,如果您希望观察者在发生服务器错误后继续听取主题,请不要将错误传递给主题,而是以其他方式处理(例如使用catchretry或将错误传递给专门的主题。)

答案 1 :(得分:4)

每个Observable都会发出零个或多个next个通知以及一个errorcomplete但不会同时发出这两个通知。

因此,受试者具有内部状态。

那么这取决于你如何构建你的链。例如,您可以使用retry()在出错时重新订阅其源Observable。

或者当您将值传递给主题时,您只能发送next个通知,而忽略其他两个:

.subscribe(v => subject.next(v));

或者,如果您想在用户null时抛出错误,您可以使用捕获异常的任何运算符并将其作为错误通知发送。例如:

.map(v => {
    if (v === null) {
        throw new Error("It's broken");
    }
    return v;
})

无论如何,如果没有任何代码,很难给出更精确的建议。