RxJava 2.x: ¿Debo usar Flowable o Single / Completable?


Estoy desarrollando una aplicación para Android usando una Arquitectura Limpia y la estoy migrando a RxJava 2.x. Tengo que hacer algunas solicitudes de red a un servicio soap, así que definí la interfaz api en el módulo de dominio:

public interface SiginterApi {
    Observable<User> login(String user, String password);
    ...
    Observable<List<Campaign>> getCampaigns(List<Long> campaignIds);
}

He leído que una solicitud de red debe hacerse con "Flowable", debido a la administración de contrapresión ya que es un 'observable frío'. Por otro lado, sé que el resultado de la solicitud será éxito (con la respuesta) o error, por lo que no se si debo usar Flowable o Single o, incluso, Observable.

Además, tengo una base de datos de accesos como este:

public interface UserRepository extends Repository {
    Observable<Void> saveUser(String username, String hashedPassword, boolean logged, User user);
    ...
    Observable<User> findUser(String username, String hashedPassword);
}

No sé si debo usar Completable/Flowable/Observable en saveUser método y Single/Flowable/Observable en findUser método.

Author: akarnokd, 2017-03-01

5 answers

La contrapresión es lo que se obtiene cuando una fuente Observable está emitiendo elementos más rápido de lo que un Subscriber puede consumirlos. Es más a menudo una preocupación con observables calientes , no fríos como sus solicitudes de red.

Creo que debería usar Completable en lugar de Observable<Void> en su método saveUser, y usar Single para todos los lugares donde siga un patrón de solicitud/respuesta o entrada/salida. Observable debe usarse cuando realmente desea un flujo continuo de eventos.

 21
Author: npace,
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-03-21 14:50:54

La contrapresión se produce cuando un Observable está emitiendo elementos más rápidamente de lo que un operador o suscriptor puede consumirlos.

Sabiendo eso, la contrapresión no es un problema en su caso, ya que su Observable emitirá solo un elemento, por lo que Flowable no es un buen candidato.

Así que la verdadera pregunta es si usar Completable o Observable para saveUser y Single o Observable para findUser y aquí como solo se espera un resultado (éxito o fracaso) en aras de la simplicidad y claridad de su API, usted debe utilizar definitivamente Completable/Single de lo contrario, será difícil entender que solo se emitirá un valor que podría ser engañoso para los usuarios de la API.

 15
Author: Nicolas Filotto,
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
2018-08-07 17:14:44

Según tengo entendido, deberías usar Single: cuando estás bastante seguro de que vas a obtener un elemento, de lo contrario obtendrías un error. Por ejemplo: GET-card/: id

Tal vez: es la solución correcta si no está tan seguro de si obtendrá un artículo. Por ejemplo: GET-card?matrícula = xvar3

Completable: cuando solo desea saber si se realizó la acción. Por ejemplo: PONER o DETELE

Observable: cuando la cantidad de elementos no es tan grande.

Fluido: cuando usted no konw la cantidad de los artículos que obtendrá.

 1
Author: Diego Marquina,
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
2018-02-21 22:20:34

Cardinalidad es una forma de entender las diferencias entre Completable, tal vez y Un:

  • A Maybe<T> es solo un Observable con cardinalidad 0 o 1, es decir, representa un resultado que puede estar presente o no.
  • Un Single<T> es un Observable que siempre devuelve un resultado, es decir, una cardinalidad de 1.
  • A Completable se puede interpretar como un Observable<Void> es decir, una cardinalidad de 0.

Así que en su caso puede cambiar la firma del repositorio de esta manera:

Completable saveUser(...);

Single<User> findUser(...);

(No mencioné Flowable s que son como Observable s con contrapresión).

 1
Author: lmarx,
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
2018-04-04 12:04:52

Hmm...

Creo que la pregunta no es trivial, mientras que, usted tiene cara situación más compleja.

Eg. Guardar usuario (REST) > Guardar usuario (SQLLite)

Es posible que desee encadenar flujos Rx en uno.

Así que o declaras

1.

Flowable<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);

Y luego use algunos de: flatMap, contactMap, switchMap

2.

... o creo que puede ser más preferible no confundir la responsabilidad de clase (puede utilizar el mismo código en muchos lugares)

Single<Response<Void>> saveUser(String username, String hashedPassword, boolean logged, User user);

RestService.saveUser(...)
.toFlowable() // Transform into Flowable 
.switchMap{ saveToDB() }
.subscribeBy{ ... }
.addTo( yourDisposable )

3.

Por cierto, sugiero no usar Completable en caso de que desee tener un buen manejo de errores. Puede fácilmente envolver Retrofit.Response<Body> en Single o Flowable para aprovechar la respuesta de código del servidor

 0
Author: murt,
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-11-27 14:32:38