Kombinieren von RxJava-Completables

RxJava Completables kombinieren

1. Überblick

In diesem Tutorial spielen wir mit dem TypRxJava’sCompletable, der ein Berechnungsergebnis ohne tatsächlichen Wert darstellt.

2. RxJava-Abhängigkeit

Nehmen wir die RxJava 2-Abhängigkeit in unser Maven-Projekt auf:


    io.reactivex.rxjava2
    rxjava
    2.2.2

Wir können normalerweise die neueste Version aufMaven Central finden.

3. Vervollständigbarer Typ

Completableis similar to Observable with the only exception that the former emits either completion or error signals but no items. DieCompletable -Skala enthält verschiedene praktische Methoden zum Erstellen oder Abrufen aus verschiedenen reaktiven Quellen.

MitCompletable.complete() können wir eine Instanz erzeugen, die sofort abgeschlossen wird.

Dann können wir seinen Zustand mitDisposableCompletableObserver beobachten:

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

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

Zusätzlich können wir eineCompletable-Instanz ausCallable, Action, and Runnable erstellen:

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

Außerdem können wirCompletable Instanzen von anderen Typen abrufen, indem wir entwederCompletable.from() verwenden oderignoreElement() fürMaybe,Single,Flowable undObservable Quellen selbst:

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

4. VerkettungCompletables

Wir können in vielen realen Anwendungsfällen eine Verkettung vonCompletables verwenden, wenn wir uns nur um den Erfolg des Betriebs kümmern:

  • All-or-nothing-Aktionen wie das Ausführen einer PUT-Anforderung zum Aktualisieren eines Remote-Objekts, gefolgt von einer lokalen Datenbankaktualisierung bei Erfolg

  • Post-factum-Protokollierung und -Journalisierung

  • Orchestrierung mehrerer Aktionen, z. Ausführen eines Analysejobs, nachdem eine Aufnahmeaktion abgeschlossen wurde

Wir halten Beispiele einfach und problemunabhängig. Angenommen, wir haben mehrereCompletable-Instanzen:

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

Wir können so vieleCompletables wie nötig verketten. Gleichzeitig sindif 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);

Weiterhinif 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.

Gut, dass wir dieses Szenario noch testen können:

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

5. Zusammenstellung einer Reihe von Completables

Stellen Sie sich vor, wir haben eine Menge vonCompletables.. Nehmen wir als praktischen Anwendungsfall an, wir müssen einen Benutzer in mehreren separaten Subsystemen registrieren.

To join all Completables into a single one, we can use the merge() family of methods. Der Operatormerge() ermöglicht das Abonnieren aller Quellen.

Die resultierende Instanzcompletes once all of the sources are completed. Außerdem wird es mitonError beendet, wenn eine der Quellen einen Fehler ausgibt:

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

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

Kommen wir zu einem etwas anderen Anwendungsfall. Angenommen, wir müssen für jedes Element, das ausFlowable. erhalten wird, eine Aktion ausführen

Dann wollen wir ein einzelnesCompletable sowohl für den Abschluss des Upstreams als auch für alle Aktionen auf Elementebene. Der OperatorflatMapCompletable () hilft in diesem Fall:

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

In ähnlicher Weise ist das obige Verfahren für den Rest der reaktiven Basisklassen wieObservable,Maybe oderSingle. verfügbar

Als praktischer Kontext fürflatMapCompletable() könnten wir darüber nachdenken, jedes Element mit einem Nebeneffekt zu dekorieren. Wir können einen Protokolleintrag für jedes abgeschlossene Element schreiben oder nach jeder erfolgreichen Aktion einen Speicher-Snapshot erstellen.

Schließlich könnenwe may need to construct a Completable from a couple of other sources and get it terminated as soon as either of them completes. Hier können die Operatoren vonambhelfen.

Das Präfixamb ist eine Abkürzung für „mehrdeutig“, was die Unsicherheit impliziert, welcheCompletable genau abgeschlossen werden. Zum BeispielambArray():

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

Beachten Sie, dass der obigeCompletable may auch mitonError() anstelle vononComplete() endet, je nachdem, welche Quelle zuerst abgeschlossen werden kann:

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

Sobald die erste Quelle endet, wird garantiert, dass die verbleibenden Quellen entsorgt werden.

Das bedeutet, dass alle verbleibenden laufendenCompletables überDisposable.dispose() gestoppt werden und die entsprechendenCompletableObservers abgemeldet werden.

In Bezug auf ein praktisches Beispiel können wiramb() verwenden, wenn wir eine Sicherungsdatei an mehrere äquivalente Remote-Speicher streamen. Und wir schließen den Vorgang ab, sobald die erste Sicherung abgeschlossen ist, oder wiederholen den Vorgang bei einem Fehler.

6. Fazit

In diesem Artikel haben wir kurz denCompletable -Styp von RxJava überprüft.

Wir haben mit verschiedenen Optionen zum Abrufen vonCompletable-Instanzen begonnen und dannCompletables mithilfe der OperatorenandThen(), merge(), flatMapCompletable(), andamb…() verkettet und zusammengesetzt.

Wir können die Quelle für alle Codebeispieleover on GitHub finden.