52 votes

Souscrire avec Vs souscrire dans RxJava2 (Android)?

Quand appeler la méthode subscribeWith plutôt que souscrire en clair? Et quel est le cas d'utilisation?

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

CONTRE

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

Je vous remercie


Ajouté plus tard

Selon la documentation, les deux instances SingleObserver jetables sont renvoyées:

 @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 Disposable.

41voto

mmaarouf Points 460

Observables#abonnez-vous explication:

Dans votre premier extrait de code:

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

Vous êtes en fait en utilisant une des plusieurs surchargé Observable#subscribe méthodes:

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

Il y en a une autre qui prend également en 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 tout simplement passer un Observer (REMARQUE: la méthode void) (Edition 2 - cette méthode est définie en ObservableSource, ce qui est l'interface que l' Observable s'étend.)

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

Dans le deuxième extrait de code dans votre question, vous avez utilisé l' subscribeWith méthode qui retourne simplement l' Observer passée dans (pratique/mise en cache, etc):

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

Observateur#onComplete explication:

Observateur#onComplete est appelé après que l'Observable a émis tous les éléments dans le flux. De la 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();

Ainsi, par exemple, si l' get() dans vos extraits de code renvoyé un Observable qui l'a émis plusieurs News objets, chacun seront traitées dans l' Observer#onNext. Ici vous pouvez traiter chaque élément.

Après qu'ils ont tous été traités (et en supposant qu'aucune erreur ne s'est produite), puis l' onComplete seront appelés. Ici vous pouvez effectuer toutes les actions supplémentaires que vous devez faire (pour exemple. mise à jour de l'INTERFACE utilisateur), sachant que vous avez traité tous les News objets.

Ce n'est pas à confondre avec l' Disposable#dispose qui est appelé lorsque l'observable flux extrémités (complet/erreur), ou manuellement par vous-même pour mettre fin à l'observation (c'est là que l' CompositeDisposable vient car il vous aide à vous débarrasser de tous vos Disposables qu'elle contient à la fois).

Si dans votre scénario de l' get() sera de retour un Observable 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 comprends toujours pas l'utilisation de subscribeWith, vous avez dit qu'il passe l'observateur de la mise en cache etc , où faut-il passer? sur complet? et de ce que j'ai compris subscribeWith n'est pas réellement la consommation de la observables( ou la Seule) à droite?

Pour clarifier davantage l' subscribeWith explication, ce que je voulais dire, c'est qu'il va consommer de l' Observer objet que vous avez passé dans l' subscribeWith (exactement comme l' subscribe méthode) cependant, il va en outre de retour que même l'Observateur le droit de retour pour 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;
}

Par conséquent, subscribeWith peut être utilisé de manière interchangeable avec l' subscribe.

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

L' subscribeWith javadoc donne des exemple d'utilisation:

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 l' subscribeWith sera de retour le même ResourceObserver objet qui a été instancié. Cela donne la commodité de l'exécution de l'abonnement et l'ajout de l' ResourceObserver de la CompositeDisposable en une seule ligne (à noter qu' ResourceObservable implémente Disposable.)

Edit 2 de la Réponse à la deuxième commentaire.

source.subscribeWith(rs); source.abonnez-vous(rs); les deux de retour SingleObserver exemple,

ObservableSource#subscribe(Observer <? super T> observer) ne PAS retourner un Observer. C'est une méthode void (Voir la NOTE sous l' Observable#abonnez-vous de l'explication ci-dessus). Alors que l' Observable#subscribeWith N' retour de l' Observer. Si nous étions à la réécriture de l'exemple d'utilisation du code à l'aide d' ObservableSource#subscribe au lieu de cela, nous aurions du 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 l' Observable#subscribeWith méthode fait commode pour nous de faire le ci-dessus en une seule ligne, composite.add(source.subscribeWith(rs));

Il peut devenir confus avec tous les surchargé de s'abonner à des méthodes qui ressemblent quelque peu similaires, cependant il y a des différences (dont certains 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

L' subscribeWith méthode est utile lorsque vous avez un spécifique de la mise en œuvre d'un Observer que vous souhaitez réutiliser. Par exemple, dans l'exemple de code ci-dessus, il a fourni une mise en œuvre spécifique de l' ResourceObserver dans l'abonnement, héritant ainsi ses fonctionnalités 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 si vous voulez faire le même abonnement pour l' get() réponse en plusieurs endroits?

Au lieu de copier l' Consumer des implémentations pour onNext et onError à travers différentes catégories, ce que vous pouvez faire à la place est de définir une nouvelle classe, par exemple.

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

Maintenant, chaque fois que vous faites cela get() demande, il vous suffit de vous abonner en faisant:

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

Voir le code est simple maintenant, vous maintenir la séparation de la responsabilité pour le traitement de la réponse, et vous pouvez désormais réutiliser GetNewsObserver où vous le souhaitez.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X