Subscribewith Vs subscribe dans RxJava2 (Android)?

Quand appeler la méthode subscribeWith plutôt que simplement subscribe? Et qu'est-ce que le cas d'utilisation?

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

Merci


Ajouté Plus Tard

Selon la documentation, les deux renvoient des instances SingleObserver jetables:

@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;
}

Où la classe ConsumerSingleObserver implémente SingleObserver et jetable.

25
demandé sur Incinerator 2017-06-20 01:21:49

1 réponses

Observables#abonnez-vous explication:

Dans votre premier extrait de code:

.abonnez-vous(c'::handleResponse, ce::handleError));

Vous utilisez en fait l'une des nombreuses méthodes Observable#subscribe surchargées:

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

Il y en a un autre qui prend aussi un Action pour effectuer onComplete:

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

Et une autre option vous permet de simplement passer dans un Observer (remarque: méthode void) (Edit 2 - cette méthode est défini dans ObservableSource, qui est l'interface que Observable étend.)

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

Dans le deuxième extrait de code de votre question, vous avez utilisé la méthode subscribeWith qui renvoie simplement le {[12] } que vous avez passé (pour plus de commodité / mise en cache, etc.):

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

Observateur#onComplete explication:

L'Observateur # onComplete est appelé après que L'Observable ait émis tous les éléments du flux. De la doc java:

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

Ainsi, par exemple, si la get() dans votre code les extraits ont renvoyé un Observable qui a émis plusieurs objets News, chacun étant géré dans le Observer#onNext. Ici vous pouvez traiter chaque élément.

Une fois qu'ils ont tous été traités (et en supposant qu'aucune erreur ne s'est produite), le onComplete sera appelé. Ici, vous pouvez effectuer des actions supplémentaires que vous devez faire (par exemple. update UI) sachant que vous avez traité tous les objets News.

Cela ne doit pas être confondu avec Disposable#dispose qui est invoqué lorsque le flux observable se termine (complete / error), ou manuellement par vous pour mettre fin à l'observation (c'est là que le CompositeDisposable entre car il vous aide à disposer de tous vos Disposables qu'il contient à la fois).

Si dans votre scénario de la get() retourne Observable, ce qui émet seulement un seul élément, alors au lieu d'utiliser un Observable, pensez à utiliser un io.reactivex.Single, où vous ne traiter que d'un point (en onSuccess), et n'aurez pas besoin de spécifier un Action pour onComplete :)

Edit: réponse à votre commentaire:

Cependant, je ne reçois toujours pas l'utilisation de subscribeWith, vous avez dit qu'il passe l'observateur pour la mise en cache etc, où passe-t-il? sur complet? et d'après ce que j'ai compris subscribeWith ne consomme pas réellement le observable (ou unique) non?

Pour clarifier davantage l'explication subscribeWith, ce que je voulais dire, c'est qu'il va consommer l'objet Observer que vous avez passé dans le subscribeWith (exactement comme la méthode subscribe) mais il sera en outre de retour de ce même Observateur droit de nouveau à vous. Au moment de la rédaction, la mise en œuvre de subscribeWith est:

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

Donc, subscribeWith peut être utilisé de manière interchangeable avec subscribe.

Pouvez-vous donner un cas d'utilisation de subscribeWith avec exemple? Je suppose que c' répondra complètement à la question

Le subscribeWith javadoc donne l'exemple d'utilisation suivant:

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

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

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

Voir ici l'utilisation de {[15] } renverra le même objet ResourceObserver qui était instancier. Cela donne la commodité d'effectuer l'abonnement et d'ajouter le ResourceObserver au CompositeDisposable en une ligne (notez que ResourceObservable implémente Disposable.)

Edit 2 répondant au deuxième commentaire.

Source.subscribeWith (rs); source.abonnez-vous (rs); les deux reviennent Instance SingleObserver,

ObservableSource#subscribe(Observer <? super T> observer) ne renvoie pas un Observer. C'est une méthode vide (Voir NOTE sous l'explication Observable#subscribe ci-dessus.) Alors que le Observable#subscribeWith est-ce que renvoie le Observer. Si nous devions réécrire l'exemple de code d'utilisation en utilisant ObservableSource#subscribe à la place, nous devrions le faire en deux lignes comme ceci:

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

Alors que la méthode Observable#subscribeWith nous a permis de faire ce qui précède en une seule ligne composite.add(source.subscribeWith(rs));

Il peut être confus avec toutes les méthodes d'abonnement surchargées qui semblent quelque peu similaires, mais il y a des différences (dont certaines sont subtiles). En regardant le code et la documentation aide à fournir la distinction entre eux.


Edit 3 un autre exemple de cas d'utilisation pour subscribeWith

La méthode subscribeWith est utile lorsque vous avez une implémentation spécifique d'un Observer que vous pouvez réutiliser. Par exemple, dans l'exemple de code ci-dessus, il a fourni une implémentation spécifique de ResourceObserver dans l'abonnement, héritant ainsi de sa fonctionnalité tout en vous permettant de gérer onNext onError et onComplete.

Un Autre exemple d'utilisation: pour l'exemple de code dans votre question, que faire si vous vouliez effectuer le même abonnement pour la réponse get() à plusieurs endroits?

Au lieu de copier les implémentations Consumer pour onNext et onError à travers différentes classes, ce que vous pouvez faire à la place est de définir une nouvelle classe pour eg.

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

Maintenant, chaque fois que vous faites cette demande get(), Vous pouvez simplement vous abonner en faisant:

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

Voir le code est simple maintenant, vous maintenez la séparation de la responsabilité pour gérer la réponse, et pouvez maintenant réutiliser cela GetNewsObserver où vous le souhaitez.

22
répondu mmaarouf 2017-07-15 06:19:39