Suscribirse con Vs suscribirse en RxJava2 (Android)?


¿Cuándo llamar al método subscribeWith en lugar de simplemente subscribe? ¿Y cuál es el caso de uso?

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

Gracias


Añadido más tarde

De acuerdo con la documentación, ambos devuelven instancias desechables de un solo observador:

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

Donde ConsumerSingleObserver class implementa SingleObserver y Desechable.

Author: Incinerator, 2017-06-20

1 answers

Observable # subscribe explicación:

En tu primer fragmento de código:

.en este caso, se trata de:]}

En realidad está utilizando uno de los varios métodos sobrecargados Observable#subscribe:

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

Hay otro que también toma en un Action para realizar onComplete:

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

Y otra opción le permite simplemente pasar un Observer (NOTA: método void) (Edición 2 - este método es definido en ObservableSource, que es la interfaz que Observable extiende.)

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

En el segundo fragmento de código de tu pregunta, usaste el método subscribeWith que simplemente devuelve el Observer que pasaste (por conveniencia/almacenamiento en caché, etc.):

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

Observer # onComplete explanation:

El observador#onComplete es llamado después de que el Observable haya emitido todos los elementos de la secuencia. Del documento 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();

Así, por ejemplo, si el get() en su código los snippets devolvieron un Observable que emitió múltiples objetos News, cada uno será manejado en el Observer#onNext. Aquí puede procesar cada elemento.

Después de que se hayan procesado todos (y suponiendo que no se haya producido ningún error), se llamará a onComplete. Aquí usted puede realizar cualquier acción adicional que usted necesita hacer(por ejemplo. actualizar IU) sabiendo que ha procesado todos los objetos News.

Esto no debe confundirse con Disposable#dispose que se invoca cuando el flujo observable termina (complete / error), o manualmente por usted para terminar la observación (aquí es donde el CompositeDisposable entra ya que le ayuda a deshacerse de todos sus Disposables que contiene a la vez).

Si en su escenario el get() devolverá un Observable que solo emite un solo elemento, entonces en lugar de usar un Observable, considere usar un io.reactivex.Single donde solo procese un elemento (en onSuccess), y no necesitará especificar un Action para onComplete:)

Editar: respuesta a su comentario:

Sin embargo todavía no consigo el uso de subscribeWith, usted dijo que pasa el observador de almacenamiento en caché, etc, ¿a dónde pasa? en completa? y por lo que entendí subscribeWith no está consumiendo realmente el observable (o Individual) ¿verdad?

Para aclarar aún más la explicación subscribeWith, lo que quise decir fue que consumirá el objeto Observer que pasó en el subscribeWith (exactamente igual que el método subscribe), sin embargo, adicionalmente devuélvele al mismo Observador. En el momento de escribir este artículo, la implementación de subscribeWith es:

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

Por lo Tanto, subscribeWith puede utilizarse indistintamente con subscribe.

¿Puede dar un caso de uso de subscribeWith con un ejemplo? Supongo que responderá a la pregunta completamente

El subscribeWith javadoc da el siguiente ejemplo de uso:

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

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

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

Ver aquí el uso de subscribeWith devolverá el mismo objeto ResourceObserver que fue instanciado. Esto da la conveniencia de realizar la suscripción y agregar el ResourceObserver al CompositeDisposable en una línea (tenga en cuenta que ResourceObservable implementa Disposable.)

Editar 2 Respondiendo al segundo comentario.

Fuente.subscribeWith (rs); fuente.suscribirse (rs); ambos retornan Instancia SingleObserver,

ObservableSource#subscribe(Observer <? super T> observer) no devuelve un Observer. Es un método void (Ver NOTA bajo el Observable#subscribe explicación anterior.) Considerando que Observable#subscribeWith devuelve el Observer. Si tuviéramos que reescribir el código de uso de ejemplo usando ObservableSource#subscribe en su lugar, tendríamos que hacerlo en dos líneas así:

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

Mientras que el método Observable#subscribeWith nos hizo conveniente hacer lo anterior en una sola línea composite.add(source.subscribeWith(rs));

Puede confundirse con todos los métodos de suscripción sobrecargados que parecen algo similares, sin embargo, hay diferencias (algunas de las cuales son sutiles). Mirar el código y la documentación ayuda a proporcionar la distinción entre ellos.


Edit 3 Otro caso de uso de ejemplo para subscribeWith

El método subscribeWith es útil cuando tiene una implementación específica de un Observer que puede querer reutilizar. Por ejemplo, en el código de ejemplo anterior, proporcionó una implementación específica de ResourceObserver en la suscripción, heredando así su funcionalidad al tiempo que le permite manejar onNext onError y onComplete.

Otro ejemplo de uso: para el código de ejemplo en su pregunta, ¿qué pasa si desea realizar la misma suscripción para la respuesta get() en varios lugares?

En lugar de copiar las implementaciones Consumer para onNext y onError en diferentes clases, lo que puede hacer es definir una nueva clase para eg.

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

Ahora, cada vez que haga esa solicitud get(), simplemente puede suscribirse haciendo:

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

Vea que el código es simple ahora, usted mantiene la separación de responsabilidad para manejar la respuesta, y ahora puede reutilizar eso GetNewsObserver donde quieras.

 22
Author: mmaarouf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-15 06:19:39