2017-08-03 124 views
5

总之: 如何在流错误后继续收听,而不是在每.subscribe之前加上.catch为什么Rxjs错误地取消订阅?

如果您需要更多的细节他们在这里:

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

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

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

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

这里是链接到RxJs源代码中的错误认购退订 https://github.com/ReactiveX/rxjs/blob/master/src/Subscriber.ts#L140

回答

5

Rx观测follow the grammarnext*(error|complete)?,这意味着它们可以产生什么errorcomplete通知已交付之后。

为什么这个问题可以从Rx design guidelines找到一个解释:

单消息,表明可观察序列已完成,确保可观察到的序列的消费者可以确定性地证明它是安全的,执行清理操作。

单个故障进一步确保可以为在多个可观察序列上工作的操作员维护中止语义。

总之,如果你希望你的观察员继续听受试者已经出现服务器错误后,也不能提供该错误的问题,而是在一些其他的方式处理它(例如使用catchretry或将错误传递给专门的主题)。

+0

明白谢谢! – mgrinko

3

每个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; 
}) 

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

+0

谢谢你将了解什么是'retry()' – mgrinko