订阅Vs订阅RxJava2(Android)?

时间:2017-06-19 22:21:50

标签: android rx-java reactive-programming rx-java2

何时调用subscribeWith方法而不是普通订阅?什么是用例?

compositeDisposable.add(get()
    .observeOn(AndroidSchedulers.mainThread())
    .subscribeOn(Schedulers.io())
    .subscribe(this::handleResponse, this::handleError));

VS

   compositeDisposable.add(get()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
              //  .subscribe(this::handleResponse, this::handleError);
                .subscribeWith(new DisposableObserver<News>() {
                    @Override public void onNext(News value) {
                        handleResponse(value);
                    }

                    @Override public void onError(Throwable e) {
                        handleError(e);
                    }

                    @Override public void onComplete() {
                       // dispose here ? why? when the whole thing will get disposed later
                       //via  compositeDisposable.dispose();  in onDestroy();
                    }
                }));

谢谢

稍后添加

根据文档,两者都返回一次性SingleObserver实例:

@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final <E extends SingleObserver<? super T>> E subscribeWith(E observer) {
    subscribe(observer);
    return observer;
}

@SchedulerSupport(SchedulerSupport.NONE)
public final Disposable subscribe(final Consumer<? super T> onSuccess, final Consumer<? super Throwable> onError) {
    ObjectHelper.requireNonNull(onSuccess, "onSuccess is null");
    ObjectHelper.requireNonNull(onError, "onError is null");
    ConsumerSingleObserver<T> s = new ConsumerSingleObserver<T>(onSuccess, onError);
    subscribe(s);
    return s;
}

ConsumerSingleObserver类实现SingleObserver和Disposable。

1 个答案:

答案 0 :(得分:30)

可观察#订阅说明

在您的第一个代码段中:

  

.subscribe(this :: handleResponse,this :: handleError));

您实际上正在使用多个重载的Observable#subscribe方法之一:

public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError)

另外还有一个Action执行onComplete:

public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError,
        Action onComplete) {

另一个选项允许您简单地传入Observer (注意:无效方法) (编辑2 - 此方法在ObservableSource中定义,是Observable扩展的界面。)

public final void subscribe(Observer<? super T> observer)

在您问题的第二个代码段中,您使用了subscribeWith方法,它只返回您传入的Observer(为方便/缓存等):

public final <E extends Observer<? super T>> E subscribeWith(E observer)

观察者#onComplete解释:

在Observable发出流中的所有项后,将调用Observer#onComplete。 来自java doc:

/**
 * Notifies the Observer that the {@link Observable} has finished sending push-based notifications.
 * <p>
 * The {@link Observable} will not call this method if it calls {@link #onError}.
 */
void onComplete();

例如,如果代码段中的get()返回了发出多个Observable个对象的News,则每个对象都会在Observer#onNext中处理。在这里,您可以处理每个项目。

完成所有处理后(并假设没有发生错误),然后调用onComplete。知道您已经处理了所有News个对象,您可以在这里执行您需要执行的任何额外操作(例如更新UI)。

这不要与可观察流结束(完成/错误)时调用的Disposable#dispose混淆,或者由您手动终止观察(这是CompositeDisposable所在的位置它可以帮助您一次性处理它包含的所有Disposable

如果在您的方案中,get()将返回仅发出单个项目的Observable,而不是使用Observable,请考虑仅使用io.reactivex.Single处理一个项目(在onSuccess中),并且不需要为onComplete指定Action:)

修改:对您的评论的回复:

  

但是我仍然没有使用subscribeWith,你说它通过了   缓存的观察者等,它传递到哪里?完成?和   从我理解的订阅与实际上并没有消费   可观察(或单一)对吗?

为了进一步澄清subscribeWith解释,我的意思是消耗您传递到Observer的{​​{1}}对象(完全类似于subscribeWith方法)但是它会另外将相同的Observer返回给您。在撰写本文时,subscribeWith的实现是:

subscribe

因此,public final <E extends Observer<? super T>> E subscribeWith(E observer) { subscribe(observer); return observer; } 可以subscribeWith互换使用。

  

您能举例说明subscribeWith的用例吗?我猜可能是   将完全回答这个问题

subscribe javadoc给出了以下用法示例:

subscribeWith

请参见此处Observable<Integer> source = Observable.range(1, 10); CompositeDisposable composite = new CompositeDisposable(); ResourceObserver<Integer> rs = new ResourceObserver<>() { // ... }; composite.add(source.subscribeWith(rs)); 的用法将返回实例化的同一subscribeWith对象。这提供了执行订阅和便利的便利性。在一行中将ResourceObserver添加到ResourceObserver(请注意CompositeDisposable实施ResourceObservable。)

编辑2 回复第二条评论。

  

source.subscribeWith(RS); source.subscribe(RS);都归来了   SingleObserver实例,

Disposable 返回ObservableSource#subscribe(Observer <? super T> observer)。这是一个void方法(参见上面 Observable#subscribe 解释下的注释。)Observer DOES 返回Observable#subscribeWith。 如果我们使用Observer重写示例使用代码,我们必须在两行中这样做:

ObservableSource#subscribe

source.subscribe(rs); //ObservableSource#subscribe is a void method so nothing will be returned composite.add(rs); 方法使我们只需一行Observable#subscribeWith

就可以方便地执行上述操作

它可能会让所有重载的订阅方法看起来有点混乱,但是存在差异(其中一些是微妙的)。查看代码和文档有助于区分它们。

<小时/> 编辑3 subscribeWith的另一个示例用例

composite.add(source.subscribeWith(rs));方法对于您可能希望重用的subscribeWith的特定实现非常有用。例如,在上面的示例代码中,它在订阅中提供了Observer的特定实现,从而继承了它的功能,同时仍允许您处理onNext onError和onComplete。

另一个示例用法:对于您问题中的示例代码,如果您想在多个位置为ResourceObserver响应执行相同的订阅该怎么办?

不是在不同的类中复制onNext和onError的get()实现,而是可以为例如。

定义一个新类。
Consumer

现在,每当您执行//sample code.. public class GetNewsObserver extends DisposableObserver<News> { //implement your onNext, onError, onComplete. .... } 请求时,您只需订阅:

即可
get()

现在看到代码很简单,你保持处理响应的责任分离,现在可以在任何你想要的地方重用compositeDisposable.add(get() ... .subscribeWith(new GetNewsObserver()));