Observables in RxJava kombinieren

1. Einführung

In diesem kurzen Lernprogramm werden verschiedene Möglichkeiten zum Kombinieren von Observables in RxJava beschrieben.

Wenn Sie RxJava noch nicht kennen, lesen Sie auf jeden Fall diesen Link:/rxjava-tutorial[Intro-Tutorial].

Lass uns jetzt gleich reinspringen.

2. Observables

Observable -Sequenzen oder einfach Observables sind Darstellungen asynchroner Datenströme.

Diese basieren auf dem Muster https://en.wikipedia.org/wiki/Observer pattern[Observer], bei dem ein Objekt namens Observer Elemente, die von einem Observable__ ausgegeben werden, abonniert.

Das Abonnement ist nicht blockierend, da der Observer darauf reagiert, was auch immer das Observable in der Zukunft ausgeben wird. Dies erleichtert wiederum die Parallelität.

Hier ist eine einfache Demonstration in RxJava:

Observable
  .from(new String[]{ "John", "Doe" })
  .subscribe(name -> System.out.println("Hello " + name))

3. Observables kombinieren

Bei der Programmierung mit einem reaktiven Framework ist es ein üblicher Anwendungsfall, verschiedene Observables zu kombinieren.

In einer Webanwendung müssen wir beispielsweise zwei voneinander unabhängige asynchrone Datenströme anfordern.

  • Anstatt auf den Abschluss des vorherigen Streams zu warten, bevor der nächste Stream angefordert wird, können wir beide gleichzeitig aufrufen und die kombinierten Streams abonnieren.

In diesem Abschnitt werden einige Möglichkeiten beschrieben, wie wir mehrere Observables in RxJava kombinieren können, und die verschiedenen Anwendungsfälle, auf die die einzelnen Methoden zutreffen.

3.1. Verschmelzen

Wir können den merge -Operator verwenden, um die Ausgabe mehrerer Observables zu kombinieren, so dass sie wie eines wirken:

@Test
public void givenTwoObservables__whenMerged__shouldEmitCombinedResults() {
    TestSubscriber<String> testSubscriber = new TestSubscriber<>();

    Observable.merge(
      Observable.from(new String[]{"Hello", "World"}),
      Observable.from(new String[]{"I love", "RxJava"})
    ).subscribe(testSubscriber);

    testSubscriber.assertValues("Hello", "World", "I love", "RxJava");
}

3.2. MergeDelayError

Die mergeDelayError -Methode ist die gleiche wie merge , da sie mehrere Observables zu einem einzigen kombiniert. Wenn jedoch Fehler beim Zusammenführen auftreten, können fehlerfreie Elemente fortgesetzt werden, bevor die Fehler weitergegeben werden. ** :

@Test
public void givenMutipleObservablesOneThrows__whenMerged__thenCombineBeforePropagatingError() {
    TestSubscriber<String> testSubscriber = new TestSubscriber<>();

    Observable.mergeDelayError(
      Observable.from(new String[]{ "hello", "world" }),
      Observable.error(new RuntimeException("Some exception")),
      Observable.from(new String[]{ "rxjava" })
    ).subscribe(testSubscriber);

    testSubscriber.assertValues("hello", "world", "rxjava");
    testSubscriber.assertError(RuntimeException.class);
}

Das obige Beispiel gibt alle fehlerfreien Werte aus :

hello
world
rxjava
  • Wenn Sie merge anstelle von mergeDelayError verwenden, wird String " rxjava" nicht ausgegeben, da merge den Datenfluss von Observables sofort stoppt, wenn ein Fehler auftritt.

3.3. Postleitzahl

Die zip -Erweiterungsmethode vereint zwei Folgen von Werten als Paare :

@Test
public void givenTwoObservables__whenZipped__thenReturnCombinedResults() {
    List<String> zippedStrings = new ArrayList<>();

    Observable.zip(
      Observable.from(new String[]{ "Simple", "Moderate", "Complex" }),
      Observable.from(new String[]{ "Solutions", "Success", "Hierarchy"}),
      (str1, str2) -> str1 + " " + str2).subscribe(zippedStrings::add);

    assertThat(zippedStrings).isNotEmpty();
    assertThat(zippedStrings.size()).isEqualTo(3);
    assertThat(zippedStrings).contains("Simple Solutions", "Moderate Success", "Complex Hierarchy");
}

3.4. Zip mit Intervall

In diesem Beispiel komprimieren wir einen Stream mit Intervall , wodurch die Ausgabe von Elementen des ersten Streams verzögert wird:

@Test
public void givenAStream__whenZippedWithInterval__shouldDelayStreamEmmission() {
    TestSubscriber<String> testSubscriber = new TestSubscriber<>();

    Observable<String> data = Observable.just("one", "two", "three", "four", "five");
    Observable<Long> interval = Observable.interval(1L, TimeUnit.SECONDS);

    Observable
      .zip(data, interval, (strData, tick) -> String.format("[%d]=%s", tick, strData))
      .toBlocking().subscribe(testSubscriber);

    testSubscriber.assertCompleted();
    testSubscriber.assertValueCount(5);
    testSubscriber.assertValues("[0]=one", "[1]=two", "[2]=three", "[3]=four", "[4]=five");
}

4. Zusammenfassung

In diesem Artikel haben wir einige Methoden zum Kombinieren von Observables mit RxJava kennen gelernt. Sie können andere Methoden kennenlernen, wie kombiniertes Update , join , groupMitgliedschaft , http://reactivex.io/documentation/operators/switch.html[switchOnNext , in Offizielle RxJava-Dokumentation .

Wie immer ist der Quellcode für diesen Artikel in unserem https://github.com/eugenp/tutorials/tree/master/rxjava [GitHub Repo verfügbar.