简体   繁体   English

订阅Vs订阅RxJava2(Android)?

[英]Subscribewith Vs subscribe in RxJava2(Android)?

When to call the subscribeWith method rather than plain subscribe? 何时调用subscribeWith方法而不是普通订阅? And what is the use case? 什么是用例?

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

VS 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();
                    }
                }));

Thank you 谢谢


Added Later 稍后添加

According to the documentation, both return disposable SingleObserver instances: 根据文档,两者都返回一次性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;
}

Where ConsumerSingleObserver class implements SingleObserver and Disposable. ConsumerSingleObserver类实现SingleObserver和Disposable的位置。

Observable#subscribe explanation: 可观察的#订阅说明:

In your first code snippet: 在您的第一个代码段中:

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

You are actually using one of the several overloaded Observable#subscribe methods: 您实际上正在使用几个重载的Observable#subscribe方法之一:

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

There is another one that also takes in an Action to perform onComplete: 还有另一个也接受一个Action来执行onComplete:

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

And another option allows you to simply pass in an Observer (NOTE: void method) (Edit 2 - this method is defined in ObservableSource , which is the interface that Observable extends.) 另一个选项允许您简单地传入Observer (注意:void方法) (编辑2 - 此方法在ObservableSource定义,它是Observable扩展的接口。)

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

In the second code snippet in your question, you used the subscribeWith method which simply returns the Observer you passed in (for convenience/caching etc): 在你问题的第二个代码片段中,你使用了subscribeWith方法,它只返回你传入的Observer (为了方便/缓存等):

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

Observer#onComplete explanation: 观察者#onComplete解释:

Observer#onComplete gets called after the Observable has emitted all the items in the stream. 在Observable发出流中的所有项后,将调用Observer#onComplete。 From the java doc: 来自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();

So for example, if the get() in your code snippets returned an Observable that emitted multiple News objects, each one will be handled in the Observer#onNext . 因此,例如,如果代码片段中的get()返回了一个发出多个News对象的Observable ,则每个对象都将在Observer#onNext处理。 Here you can process each item. 在这里,您可以处理每个项目。

After they have all been processed (and assuming no error occured), then the onComplete will get called. 在完成所有处理之后(假设没有发生错误),将调用onComplete Here you can perform any extra actions that you need to do (for eg. update UI) knowing that you've processed all the News objects. 知道您已经处理了所有News对象,您可以在这里执行您需要执行的任何额外操作(例如,更新UI)。

This is not to be confused with Disposable#dispose which gets invoked when the observable stream ends (complete/error), or manually by you to terminate the observation (this is where the CompositeDisposable comes in as it helps you dispose of all your Disposable s that it contains at once). 这不要与Disposable#dispose混淆,后者在可观察流结束时(完成/错误)被调用,或者由您手动终止观察(这是CompositeDisposable进入的地方,因为它可以帮助您处理所有的Disposable s它立即包含)。

If in your scenario the get() will return an Observable that only emits a single item, then instead of using an Observable , consider using an io.reactivex.Single where you only process the one item (in onSuccess ), and won't need to specify an Action for onComplete :) 如果您的方案get()会返回一个Observable ,仅发出一个单一的项目,然后而不是使用Observable ,可考虑使用io.reactivex.Single ,你只处理一个项目(在onSuccess ),并且不会需要为onComplete指定一个Action :)

Edit : response to your comment: 编辑 :回复您的评论:

However I still do not get use of subscribeWith, you said it passes the observer for caching etc , where does it pass to? 但是我仍然没有使用subscribeWith,你说它通过观察者进行缓存等,它传递到哪里? on complete? 完成? and from what I understood subscribeWith is not actually consuming the observable( or Single) right? 从我所理解的订阅中,实际上并没有消费可观察(或单一)的权利?

To further clarify the subscribeWith explanation, what I meant was that it will consume the Observer object that you passed into the subscribeWith (exactly like the subscribe method) however it will additionally return that same Observer right back to you. 为了进一步阐明subscribeWith解释,我的意思是它将使用你传递给subscribeWithObserver对象(与subscribe方法完全相同),但是它还会将相同的Observer返回给你。 At time of writing, the implementation of subscribeWith is: 在撰写本文时,subscribeWith的实现是:

public final <E extends Observer<? super T>> E subscribeWith(E observer) {
    subscribe(observer);
    return observer;
}

Therefore, subscribeWith can be used interchangeably with subscribe . 因此, subscribeWith 可以subscribe互换使用。

Can you give a use case of subscribeWith with example? 你能举例说明subscribeWith的用例吗? I guess that will answer the question completely 我想这完全可以回答这个问题

The subscribeWith javadoc gives the following usage example: subscribeWith javadoc给出了以下用法示例:

Observable<Integer> source = Observable.range(1, 10);
CompositeDisposable composite = new CompositeDisposable();

ResourceObserver<Integer> rs = new ResourceObserver<>() {
     // ...
};

composite.add(source.subscribeWith(rs));

See here the usage of subscribeWith will return that same ResourceObserver object that was instantiated. 在这里看到subscribeWith的用法将返回实例化的相同ResourceObserver对象。 This gives the convenience of performing the subscription & adding the ResourceObserver to the CompositeDisposable in one line (note that ResourceObservable implements Disposable .) 这样可以方便地执行订阅并将ResourceObserver添加到一行中的CompositeDisposable (请注意, ResourceObservable实现了Disposable 。)

Edit 2 Replying to second comment. 编辑2回复第二条评论。

source.subscribeWith(rs); source.subscribeWith(RS); source.subscribe(rs); source.subscribe(RS); both return SingleObserver instance, 两者都返回SingleObserver实例,

ObservableSource#subscribe(Observer <? super T> observer) does NOT return an Observer . ObservableSource#subscribe(Observer <? super T> observer) 返回Observer It is a void method (See NOTE under the Observable#subscribe explanation above.) Whereas the Observable#subscribeWith DOES return the Observer . 它是一个void方法(参见上面Observable#subscribe解释下的注释。) Observable#subscribeWith DOES返回Observer If we were to rewrite the example usage code using ObservableSource#subscribe instead, we'd have to do it in two lines like so: 如果我们使用ObservableSource#subscribe重写示例用法代码,我们必须在两行中这样做:

source.subscribe(rs); //ObservableSource#subscribe is a void method so nothing will be returned
composite.add(rs);

Whereas the Observable#subscribeWith method made it convenient for us to do the above in just one line composite.add(source.subscribeWith(rs)); Observable#subscribeWith方法使我们只需一行composite.add(source.subscribeWith(rs));

It can get confusing with all the overloaded subscribe methods that look somewhat similar, however there are differences (some of which are subtle). 它可能会让所有看起来有点类似的重载订阅方法变得混乱,但是存在差异(其中一些是微妙的)。 Looking at the code and documentation helps to provide the distinction between them. 查看代码和文档有助于区分它们。


Edit 3 Another sample use case for subscribeWith 编辑3 subscribeWith的另一个示例用例

The subscribeWith method is useful for when you have a specific implementation of an Observer that you may want to reuse. 当您具有可能要重用的Observer的特定实现时, subscribeWith方法很有用。 For example, in the sample code above, it provided a specific implementation of ResourceObserver in the subscription, thereby inheriting it's functionality while still allowing you to handle onNext onError and onComplete. 例如,在上面的示例代码中,它在订阅中提供了ResourceObserver的特定实现,从而继承了它的功能,同时仍允许您处理onNext onError和onComplete。

Another example use: for to the sample code in your question, what if you wanted to perform the same subscription for the get() response in multiple places? 另一个示例用法:对于您问题中的示例代码,如果您想在多个位置为get()响应执行相同的订阅,该怎么办?

Instead of copying the Consumer implementations for onNext and onError across different classes, what you can do instead is define a new class for eg. 不是在不同的类中复制onNext和onError的Consumer实现,而是可以为例如定义一个新类。

 //sample code.. public class GetNewsObserver extends DisposableObserver<News> { //implement your onNext, onError, onComplete. .... } 

Now, whenever you do that get() request, you can simply subscribe by doing: 现在,无论何时执行get()请求,您都可以通过以下方式订阅:

 compositeDisposable.add(get() ... .subscribeWith(new GetNewsObserver())); 

See the code is simple now, you maintain separation of responsibility for handling the response, and can now reuse that GetNewsObserver wherever you want. 现在看代码很简单,你保持处理响应的责任分离,现在可以在任何你想要的地方重用GetNewsObserver

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM