do Operators instead of a whole Subscriber

烈酒焚心 提交于 2019-12-05 18:31:56

Both approaches aren't quite the same, and you're going to get some surprises out of the first:

First surprise will be that doOnError doesn't consume the error, but only performs some action on it. Consequently, in your case if the stream generates an error, it'll go through your doOnError code, and right after that trigger an OnErrorNotImplementedException, exactly as if the doOnError step wasn't there.

Let's say you realize that, and add an empty error handler to your subscribe call:

Observable
    .just(readFromDatabase())
    .doOnError(...)
    .subscribe(..., error -> { /* already handled */ } );

Then you can meet the next subtle difference. do* blocks are considered part of the stream, which means that any uncatched exception in the block will result in a stream error (as opposed with exceptions thrown in 'onNext/OnError/onComplete' blocks, which get either ignored or immediately thrown, canceling the subscription on their way).

So in the above sample, if we say your database read triggers a stream error A, which gets passed to the doOnError block, which throws an exception B, then the (empty) subscription error handler we added will receive B (and only B).

The later difference isn't very concerning for doOnError (because anyway the stream gets terminated), but can be pretty surprising when occuring in doOnNext, where an exception has a very different behavior than the same exception thrown in subscribe onNext block (error'ed stream versus implicitly canceled stream).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!