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