做运营商而不是整个订阅者 [英] do Operators instead of a whole Subscriber

查看:33
本文介绍了做运营商而不是整个订阅者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当您只需要 OnNext() 时,使用 Action(s) 而不是整个 Subscriber 非常有吸引力,因为它更具可读性.但当然,错误会发生,如果您只使用 Action1,您的应用程序中会出现 Exception.do operators 可以在这里提供帮助.我只是担心这两种方法完全相同,请确认或不确认.有什么陷阱吗?

It's quite appealing to use Action(s) instead of a whole Subscriber when you only need OnNext() merely because it's more readable. But of course, errors happen and if you only use Action1 you'll get an Exception in your app. do operators can be of help here. I'm only concerned these two approaches are fully the same, please confirm or disconfirm. Any pitfalls?

第一种方法:

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!
          }
        });

谢谢!

推荐答案

两种方法并不完全相同,你会从第一种方法中得到一些惊喜:

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

第一个惊喜是 doOnError 不会消耗错误,而只会对其执行一些操作.因此,在您的情况下,如果流生成错误,它将通过您的 doOnError 代码,然后立即触发 OnErrorNotImplementedException,就像 doOnError 步骤不存在.

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 */ } );

然后你就可以看到下一个细微的差别了.do* 块被认为是流的一部分,这意味着块中任何未捕获的异常都将导致流错误(与在onNext/OnError/onComplete"块中抛出的异常相反,它会得到要么被忽略,要么立即抛出,在途中取消订阅).

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).

所以在上面的例子中,如果我们说你的数据库读取触发了一个流错误 A,它被传递到 doOnError 块,它抛出一个异常 B,那么我们添加的(空)订阅错误处理程序将收到 B(并且只有 B).

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).

后面的区别对于 doOnError 来说不是很重要(因为无论如何流都会被终止),但是当发生在 doOnNext 中时可能会非常令人惊讶,其中异常有与 subscribe onNext 块中抛出的相同异常截然不同的行为(错误流与隐式取消流).

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).

这篇关于做运营商而不是整个订阅者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆