Combinaison de RxJava Completables

Combinaison de RxJava Completables

1. Vue d'ensemble

Dans ce tutoriel, nous allons jouer avec le typeRxJava’sCompletable, qui représente un résultat de calcul sans valeur réelle.

2. Dépendance RxJava

Incluons la dépendance RxJava 2 dans notre projet Maven:


    io.reactivex.rxjava2
    rxjava
    2.2.2

Nous pouvons généralement trouver la dernière version surMaven Central.

3. Type Completable

Completableis similar to Observable with the only exception that the former emits either completion or error signals but no items. La sclasseCompletable contient plusieurs méthodes pratiques pour la créer ou l'obtenir à partir de différentes sources réactives.

Nous pouvons générer une instance qui se termine immédiatement en utilisantCompletable.complete().

Ensuite, nous pouvons observer son état en utilisantDisposableCompletableObserver:

Completable
  .complete()
  .subscribe(new DisposableCompletableObserver() {
    @Override
    public void onComplete() {
        System.out.println("Completed!");
    }

    @Override
    public void onError(Throwable e) {
        e.printStackTrace();
    }
});

De plus, nous pouvons construire une instanceCompletable à partir deCallable, Action, and Runnable:

Completable.fromRunnable(() -> {});

De plus, nous pouvons obtenir des instancesCompletable d'autres types en utilisant soitCompletable.from(), soit en appelantignoreElement() surMaybe,Single,Flowable etObservable sources elles-mêmes:

Flowable flowable = Flowable
  .just("request received", "user logged in");
Completable flowableCompletable = Completable
  .fromPublisher(flowable);
Completable singleCompletable = Single.just(1)
  .ignoreElement();

4. ChaînageCompletables

Nous pouvons utiliser le chaînage deCompletables dans de nombreux cas d'utilisation du monde réel lorsque nous ne nous soucions que du succès de l'opération:

  • Actions tout ou rien comme faire une requête PUT pour mettre à jour un objet distant suivi d'une mise à jour de la base de données locale en cas de succès

  • Consignation et journalisation post-mémoire

  • Orchestration de plusieurs actions, par exemple exécution d'un travail d'analyse après la fin d'une action d'ingestion

Nous garderons des exemples simples et indépendants des problèmes. Considérons que nous avons plusieurs instancesCompletable:

Completable first = Completable
  .fromSingle(Single.just(1));
Completable second = Completable
  .fromRunnable(() -> {});
Throwable throwable = new RuntimeException();
Completable error = Single.error(throwable)
  .ignoreElement();

To combine two Completables into a single one, we can use the andThen() operator:

first
  .andThen(second)
  .test()
  .assertComplete();

Nous pouvons enchaîner autant deCompletablesque nécessaire. En même temps,if at least one of the sources fails to complete, resulting Completable won’t fire onComplete() as well:

first
  .andThen(second)
  .andThen(error)
  .test()
  .assertError(throwable);

De plus,if one of the sources is infinite or doesn’t reach onComplete for some reason, the resulting Completable will never fire onComplete() nor onError() as well.

Une bonne chose que nous pouvons toujours tester ce scénario:

...
  .andThen(Completable.never())
  .test()
  .assertNotComplete();

5. Composer des séries de complets

Imaginons que nous ayons un groupe deCompletables. Comme cas d'utilisation pratique, supposons que nous devions enregistrer un utilisateur dans plusieurs sous-systèmes séparés.

To join all Completables into a single one, we can use the merge() family of methods. L'opérateurmerge() permet de s'abonner à toutes les sources.

L'instance résultantecompletes once all of the sources are completed. De plus, il se termine paronError lorsque l'une des sources émet une erreur:

Completable.mergeArray(first, second)
  .test()
  .assertComplete();

Completable.mergeArray(first, second, error)
  .test()
  .assertError(throwable);

Passons à un cas d'utilisation légèrement différent. Disons que nous devons exécuter une action pour chaque élément obtenu à partir d'unFlowable.

Ensuite, nous voulons un seulCompletable à la fois pour l'achèvement de l'amont et pour toutes les actions au niveau de l'élément. L'opérateurflatMapCompletable () vient aider dans ce cas:

Completable allElementsCompletable = Flowable
  .just("request received", "user logged in")
  .flatMapCompletable(message -> Completable
      .fromRunnable(() -> System.out.println(message))
  );
allElementsCompletable
  .test()
  .assertComplete();

De même, la méthode ci-dessus est disponible pour le reste des classes réactives de base telles queObservable,Maybe ouSingle.

Comme contexte pratique pourflatMapCompletable(), nous pourrions penser à décorer chaque élément avec un effet secondaire. Nous pouvons écrire une entrée de journal par élément terminé ou créer un instantané de stockage à chaque action réussie.

Enfin,we may need to construct a Completable from a couple of other sources and get it terminated as soon as either of them completes. C'est là que les opérateursamb peuvent vous aider.

Le préfixeamb est un raccourci pour «ambigu», ce qui implique l'incertitude sur laquelleCompletable est exactement complété. Par exemple,ambArray():

Completable.ambArray(first, Completable.never(), second)
  .test()
  .assertComplete();

Notez que le smayCompletable ci-dessus se termine également paronError() au lieu deonComplete() selon la source complétable qui se termine en premier:

Completable.ambArray(error, first, second)
  .test()
  .assertError(throwable);

De plus, une fois que la première source est terminée, les sources restantes sont assurées d'être éliminées.

Cela signifie que tous lesCompletables en cours d'exécution restants sont arrêtés viaDisposable.dispose() et lesCompletableObservers correspondants seront désabonnés.

Concernant un exemple pratique, nous pouvons utiliseramb() lorsque nous diffusons un fichier de sauvegarde vers plusieurs stockages distants équivalents. Et nous terminons le processus une fois que la première sauvegarde est terminée ou répétons le processus en cas d'erreur.

6. Conclusion

Dans cet article, nous avons brièvement passé en revue le stypeCompletable de RxJava.

Nous avons commencé avec différentes options pour obtenir des instances deCompletable, puis avons chaîné et composéCompletables en utilisant les opérateursandThen(), merge(), flatMapCompletable(), andamb…().

Nous pouvons trouver la source de tous les échantillons de codeover on GitHub.