single rxkotlin rxjava rxandroid javarx examples example create android rx-java reactive-programming rx-java2

android - rxjava - rxkotlin



¿Suscribirse con Vs suscribirse en RxJava2(Android)? (1)

Observable # explicación de suscripción:

En tu primer fragmento de código:

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

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

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

Hay otro que también toma una Action para realizar en Completo:

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 de anulación) (Edición 2: este método se define en ObservableSource , que es la interfaz que se extiende en Observable ).

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

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

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

Observador # en Explicación completa:

Observador # onComplete recibe una llamada después de que el Observable ha emitido todos los elementos en la transmisión. Desde el 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();

Entonces, por ejemplo, si el get() en sus fragmentos de código devolvió un Observable que emitió múltiples objetos de News , cada uno se manejará en el Observer#onNext . Aquí puedes procesar cada elemento.

Después de que todos hayan sido procesados ​​(y suponiendo que no haya ocurrido ningún error), se onComplete a onComplete . Aquí puede realizar cualquier acción adicional que necesite realizar (por ejemplo, actualizar UI) sabiendo que ha procesado todos los objetos de News .

Esto no debe confundirse con el Disposable#dispose que se invoca cuando finaliza el flujo observable (completo / error), o manualmente para finalizar la observación (aquí es donde entra en CompositeDisposable el CompositeDisposable ya que le ayuda a deshacerse de todos sus Disposable ). 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 procesa el único elemento (en onSuccess ), y no lo hará. Necesito especificar una Action para onComplete :)

Editar : respuesta a tu comentario:

Sin embargo, todavía no utilizo subscribeWith, usted dijo que pasa el observador para el almacenamiento en caché, etc. ¿A dónde pasa? en completo? y por lo que entendí, suscribirme con no está consumiendo el derecho observable (o único).

Para aclarar aún más la subscribeWith explicación, lo que quise decir es que consumirá el objeto Observer que pasaste a la subscribeWith (exactamente igual que el método de subscribe ), sin embargo, también te devolverá ese mismo Observer. Al momento de escribir, 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 se puede usar indistintamente con subscribe .

¿Puedes dar un caso de uso de subscribeWith con ejemplo? Supongo que eso responderá la pregunta completamente.

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

Vea aquí el uso de subscribeWith devolverá el mismo objeto ResourceObserver que se creó una instancia. Esto brinda 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.

source.subscribeWith (rs); fuente.subscribe (rs); ambos devuelven instancia de SingleObserver,

ObservableSource#subscribe(Observer <? super T> observer) NO devuelve un Observer . Es un método nulo (vea la NOTA en la explicación de suscripción de Observable # arriba). Mientras que la Observer Observable#subscribeWith devuelve el Observer . Si tuviéramos que volver a escribir el código de uso de ejemplo utilizando ObservableSource#subscribe 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 hizo que sea conveniente para nosotros 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, existen diferencias (algunas de las cuales son sutiles). Mirar el código y la documentación ayuda a proporcionar la distinción entre ellos.

Edición 3 Otro caso de uso de muestra para subscribeWith

El método subscribeWith es útil cuando tiene una implementación específica de un Observer que tal vez desee 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 y al mismo tiempo le permite manejar onNext onError y onComplete.

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

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

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

Ahora, cuando haga esa solicitud get() , simplemente puede suscribirse haciendo lo siguiente:

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

Ver que el código es simple ahora, mantienes la separación de responsabilidad para manejar la respuesta y ahora puedes reutilizar ese GetNewsObserver donde quieras.

¿Cuándo llamar al método subscribeWith en lugar de la suscripción simple? ¿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

Según la documentación, ambos devuelven instancias desechables de 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; }

Donde la clase ConsumerSingleObserver implementa SingleObserver y Disposable.