Het combineren van RxJava Completables

1. Overzicht

In deze tutorial spelen we met RxJava's Voltooibaar type, dat een berekeningsresultaat vertegenwoordigt zonder een werkelijke waarde.

2. RxJava-afhankelijkheid

Laten we de RxJava 2-afhankelijkheid opnemen in ons Maven-project:

 io.reactivex.rxjava2 rxjava 2.2.2 

Meestal kunnen we de laatste versie vinden op Maven Central.

3. Voltooi type

Voltooibaar is gelijkaardig aan Waarneembaar met als enige uitzondering dat de eerste voltooiings- of foutsignalen afgeeft, maar geen items. De Voltooibaar class bevat verschillende gemakkelijke methoden voor het maken of verkrijgen van verschillende reactieve bronnen.

We kunnen een instantie spawnen die onmiddellijk wordt voltooid door Voltooi. Compleet ().

Vervolgens kunnen we zijn toestand observeren door te gebruiken DisposableCompletableObserver:

Completable .complete () .subscribe (nieuwe DisposableCompletableObserver () {@Override public void onComplete () {System.out.println ("Completed!");} @Override public void onError (Throwable e) {e.printStackTrace (); }});

Bovendien kunnen we een Voltooibaar instantie van Oproepbaar, actie en uitvoerbaar:

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

We kunnen ook krijgen Voltooibaar instanties van andere typen die een van beide gebruiken Completable.from () of bellen ignoreElement () op Misschien, Enkele, Vloeiende en Waarneembare bronnen zelf:

Flowable flowable = Flowable .just ("aanvraag ontvangen", "gebruiker ingelogd"); Completable flowableCompletable = Completable .fromPublisher (flowable); Voltooibare singleCompletable = Single.just (1) .ignoreElement ();

4. Chaining Voltooiingen

We kunnen chaining gebruiken van Voltooiingen in veel praktijkgevallen waarin we alleen geven om het succes van de operatie:

  • Alles-of-niets-acties zoals het doen van een PUT-verzoek om een ​​extern object bij te werken, gevolgd door een lokale database-update als het succes is gelukt
  • Post-factum logboekregistratie en journaling
  • Orkestratie van verschillende acties, bijv. het uitvoeren van een analysetaak nadat een opnameactie is voltooid

We houden voorbeelden simpel en probleem-agnostisch. Bedenk dat we er meerdere hebben Voltooibaar gevallen:

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

Om twee te combineren Voltooiingen in een enkele kunnen we de en dan() operator:

eerste .andThen (tweede) .test () .assertComplete ();

We kunnen er zoveel aan ketenen Voltooiingen indien nodig. Tegelijkertijd, als ten minste een van de bronnen niet wordt voltooid, resulteert Voltooibaar zal niet vuren onComplete () ook:

eerste .andThen (tweede) .andThen (fout) .test () .assertError (werpbaar);

Verder als een van de bronnen oneindig is of niet reikt onComplete om een ​​of andere reden, het resulterende Voltooibaar zal nooit vuren onComplete () noch onError () ook.

Een goede zaak dat we dit scenario nog steeds kunnen testen:

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

5. Samenstellen van een reeks voltooide items

Stel je voor dat we er een heleboel hebben Voltooiingen. Stel dat we voor het praktische gebruik een gebruiker moeten registreren binnen verschillende afzonderlijke subsystemen.

Om je bij iedereen aan te sluiten Voltooiingen in een enkele kunnen we de samenvoegen() familie van methoden. De samenvoegen() operator maakt het mogelijk om op alle bronnen te abonneren.

De resulterende instantie voltooid zodra alle bronnen zijn voltooid. Bovendien eindigt het met onError wanneer een van de bronnen een foutmelding geeft:

Completable.mergeArray (eerste, tweede) .test () .assertComplete (); Completable.mergeArray (eerste, tweede, fout) .test () .assertError (throwable);

Laten we naar een iets andere use-case gaan. Laten we zeggen dat we een actie moeten uitvoeren voor elk element dat is verkregen uit een Vloeiend.

Dan willen we een single Voltooibaar voor zowel de voltooiing van de stroomopwaartse als alle acties op elementniveau. De flatMapCompletable() operator helpt in dit geval:

Completable allElementsCompletable = Flowable .just ("aanvraag ontvangen", "gebruiker ingelogd") .flatMapCompletable (bericht -> Completable .fromRunnable (() -> System.out.println (bericht))); allElementsCompletable .test () .assertComplete ();

Evenzo is de bovenstaande methode beschikbaar voor de rest van de basale reactieve klassen zoals Waarneembaar, Kan zijn, of Single.

Als praktische context voor flatMapCompletable (), zouden we kunnen overwegen om elk item met een bijwerking te versieren. We kunnen een logboekinvoer per voltooid element schrijven of een opslagmomentopname maken bij elke succesvolle actie.

Tenslotte, we moeten mogelijk een Voltooibaar uit een paar andere bronnen en laat het beëindigen zodra een van beide is voltooid. Dat is waar amb operators kunnen helpen.

De amb prefix is ​​een korte hand voor "dubbelzinnig", wat de onzekerheid impliceert waarover Voltooibaar wordt precies voltooid. Bijvoorbeeld, ambArray ():

Completable.ambArray (eerste, Completable.never (), tweede) .test () .assertComplete ();

Merk op dat het bovenstaande Voltooibaar kan ook eindigen met onError () in plaats van onComplete () afhankelijk van welke bron het eerst beëindigt:

Completable.ambArray (fout, eerste, tweede) .test () .assertError (werpbaar);

Zodra de eerste bron is beëindigd, wordt gegarandeerd dat de resterende bronnen worden verwijderd.

Dat betekent dat alles blijft rennen Voltooiingen worden gestopt via Disposable.dispose () en de bijbehorende CompletableObservers worden afgemeld.

We kunnen een praktisch voorbeeld gebruiken amb () wanneer we een back-upbestand streamen naar een aantal equivalente externe opslagplaatsen. En we voltooien het proces zodra de eerste-beste back-up is voltooid of herhalen het proces bij een fout.

6. Conclusie

In dit artikel hebben we kort de Voltooibaar type RxJava.

We zijn begonnen met verschillende opties om te verkrijgen Voltooibaar instanties en vervolgens geketend en samengesteld Voltooiingen door de andThen (), merge (), flatMapCompletable (), en amb… () operators.

We kunnen de bron voor alle codevoorbeelden vinden op GitHub.