做运营商而不是整个订户
当你只需要OnNext()
仅仅因为它更具可读性时,使用Action
而不是整个Subscriber
是非常有吸引力的。 但是,当然会发生错误,如果您只使用Action1
,您的应用程序中会出现Exception
。 在这里, 运营商可以提供帮助。 我只关心这两种方法是完全一样的,请确认或否认。 任何陷阱?
第一种方法:
Observable .just(readFromDatabase()) .doOnError(new Action1() { @Override public void call(Throwable throwable) { // handle error } }).subscribe(new Action1() { @Override public void call(SomeData someData) { // react! } });
第二种方法:
Observable .just(readFromDatabase()) .subscribe(new Subscriber() { @Override public void onCompleted() { // do nothing } @Override public void onError(Throwable e) { // handle error } @Override public void onNext(SomeData someData) { // react! } });
谢谢!
两种方法都不尽相同,你会从第一种方法中得到一些惊喜:
第一个惊喜是doOnError
不消耗错误,但只对它执行一些操作。 因此,在您的情况下,如果流生成错误,它将通过您的doOnError
代码,并在此之后触发OnErrorNotImplementedException
,就像doOnError
步骤不存在一样。
假设你意识到这一点,并为你的订阅调用添加一个空的error handling程序:
Observable .just(readFromDatabase()) .doOnError(...) .subscribe(..., error -> { /* already handled */ } );
然后你就可以遇到下一个微妙的差异。 do*
块被认为是流的一部分,这意味着块中任何未捕获的exception都将导致流错误(与’onNext / OnError / onComplete’块中抛出的exception相反,它们被忽略或立即抛出,取消他们的订阅方式)。
所以在上面的示例中,如果我们说你的数据库读取触发了一个流错误A
,它被传递给doOnError
块,它抛出一个exceptionB
,那么我们添加的(空)订阅error handling程序将收到B
(并且只有B
) 。
稍后的差异对于doOnError
并不是非常关注(因为无论如何流都被终止),但是在doOnNext
出现时可能会非常令人惊讶,其中exception与订阅onNext
块中抛出的相同exception具有非常不同的行为(错误的流与隐式取消的流)。