web-dev-qa-db-fra.com

RxJava 2.x: Dois-je utiliser Flowable ou Single / Completable?

Je développe une Android utilisant une architecture propre et je la migre vers RxJava 2.x. Je dois faire des requêtes réseau à un service soap, j'ai donc défini l'interface api dans le module de domaine:

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

J'ai lu qu'une demande de réseau devrait être faite avec "Flowable", à cause de la gestion de la contre-pression car c'est un "observable à froid". D'un autre côté, je sais que le résultat de la demande sera un succès (avec la réponse) ou une erreur, donc je ne sais pas si je dois utiliser Flowable ou Single ou même Observable.

De plus, j'ai une base de données accède comme ceci:

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

Je ne sais pas si je dois utiliser Completable/Flowable/Observable dans saveUser méthode et Single/Flowable/Observable dans la méthode findUser.

35

La contre-pression est ce que vous obtenez quand une source Observable émet des éléments plus rapidement qu'une Subscriber ne peut les consommer. Il s'agit le plus souvent d'un problème avec chaud observables, pas froid ceux comme vos requêtes réseau.

Je pense que vous devriez utiliser Completable au lieu de Observable<Void> dans votre méthode saveUser et utilisez Single pour tous les endroits où vous suivez un modèle de demande/réponse ou d'entrée/sortie. Observable doit être utilisé lorsque vous voulez réellement un flux continu d'événements.

35
npace

Contre-pression se produit lorsque un Observable émet des éléments plus rapidement qu'un opérateur ou un abonné ne peut les consommer .

Sachant cela, la contre-pression n'est pas un problème dans votre cas car votre Observable n'émettra qu'un seul élément donc Flowable n'est pas un bon candidat.

Donc, la vraie question est de savoir s'il faut utiliser Completable ou Observable pour saveUser et Single ou Observable pour findUser et ici comme un seul résultat est attendu (succès ou échec) pour des raisons de simplicité et de clarté de votre API, vous devez définitivement utiliser Completable/Single sinon il sera difficile de comprendre qu'un seul une valeur sera émise, ce qui pourrait induire en erreur vos utilisateurs d'API.

17
Nicolas Filotto

La cardinalité est une façon de comprendre les différences entre Completable , Peut-être et Unique :

  • UNE Maybe<T> est juste un observable avec une cardinalité 0 ou 1, c'est-à-dire qu'il représente un résultat qui peut être présent ou non.
  • UNE Single<T> est un observable qui renvoie toujours un résultat, c'est-à-dire une cardinalité de 1.
  • Un Completable peut être interprété comme un Observable<Void> c'est-à-dire une cardinalité de 0.

Donc, dans votre cas, vous pouvez modifier la signature du référentiel de cette façon:

Completable saveUser(...);

Single<User> findUser(...);

(Je n'ai pas mentionné Flowables qui sont comme Observables avec contre-pression ).

8
lmarx

Si je comprends bien, vous devez utiliser Single: lorsque vous êtes presque sûr d'obtenir un article, sinon vous obtiendrez une erreur. Par exemple: GET - card /: id

Peut-être: est la bonne solution si vous n'êtes pas sûr si vous obtiendrez un article. Par exemple: GET - card? License-plate = xvar3

Completable: lorsque vous voulez seulement savoir si l'action a été effectuée. Par exemple: PUT ou DETELE

Observable: lorsque la quantité d'articles n'est pas si importante.

Fluide: lorsque vous ne connaissez pas la quantité d'articles que vous obtiendrez.

2
dmarquina

Hmm ...

Je pense que la question n'est pas anodine alors que vous avez une situation plus complexe.

Par exemple. Enregistrer l'utilisateur (REST)> Enregistrer l'utilisateur (SQLlite)

Vous voudrez peut-être chaîne flux Rx en un seul.

Donc, soit vous déclarez

1.

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

puis utilisez une partie de: flatMap, contactMap, switchMap

2.

... ou je pense qu'il peut être préférable de ne pas confondre la responsabilité de classe (vous pouvez utiliser le même code à de nombreux endroits)

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

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

3.

Au fait, je suggère de ne pas utiliser Completable au cas où vous voudriez avoir une bonne gestion des erreurs. Vous pouvez facilement envelopper Retrofit.Response<Body> dans Single ou Flowable pour profiter de la réponse du code du serveur

0
murt