正确的方法来处理" onNext"热门,共享,可观察

时间:2016-03-02 07:21:01

标签: javascript reactive-programming rxjs reactive-extensions-js rxjs5

在RxJS第5版中,以下代码导致在两次订阅的三次迭代后终止进程:

var Rx = require("rxjs");

const published$ = Rx.Observable.interval(1000).publish();

published$.subscribe(index => {
    console.log(`One: ${index}`);

    if (index == 3) throw new Error("ded.");
});

published$.forEach(index => {
    console.log(`Two: ${index}`);
});

published$.connect();

但是,我的理解是,下一个处理程序中抛出的错误只是取消订阅该特定订阅,而不会导致底层observable终止。我的预期输出将是" One"订阅将取消订阅,但间隔将继续产生结果到"二"订阅。

这种行为导致了我的问题,我可能会对底层的热可观察对象进行多次预订 - 但是在这些预订中抛出的单个异常会导致底层的observable完全终止。

当我使用热模块重新加载进行开发时,它特别烦人,因为任何订阅中的任何编程错误都会导致我必须刷新整个页面以重新启动可观察序列。

有没有一种方法,如果没有在try / catch中包装我的每个订阅,在我的下一个处理程序中抛出异常只是取消订阅该ONE订阅,而不是终止底层的observable?

------------编辑------------

通过在" subscribe"返回的订阅对象上将syncErrorThrowable设置为true,我找到了我正在寻找的行为。似乎在代码库中唯一一次设置为true的时间是通过" do"操作

我应该利用这个领域吗?我觉得使用它很脏,但另一方面我觉得很奇怪"做"运算符具有与" next"不同的错误处理语义。订阅处理程序。

这是受此标志影响的主要代码块: https://github.com/ReactiveX/RxJS/blob/master/src%2FSubscriber.ts#L132

如果将其设置为false,则会调用此方法: https://github.com/ReactiveX/RxJS/blob/master/src%2FSubscriber.ts#L179

如果它设置为true,则使用此方法: https://github.com/ReactiveX/RxJS/blob/master/src%2FSubscriber.ts#L188

不同之处在于第一个方法会将异常重新抛出回调用堆栈,而第二个方法则将错误传播到后续订阅。

为什么do运算符向前传播错误,而" next"处理程序冒泡错误备份?这对我来说似乎很奇怪。

1 个答案:

答案 0 :(得分:1)

不,不要使用该字段。如果您将其更改回true,您的订阅将开始吞咽错误。

这是一个私有状态我们用来知道订阅是同步通知(与源Observable的订阅调用在同一个块中),还是异步通知。如果在同步通知期间从其中一个订阅者的消息处理程序抛出错误,我们会推迟重新抛出它,直到我们退出Observable的订阅回调。[1]

如果您的处理程序抛出了您希望转发给订阅的onError处理程序的错误,那么本指南就是将它们移到订阅上方的do块中。

不,我不同意这种行为。以下是一些上下文链接:

[1]来源:我写了这段代码。