RxSwift – Grundlagen und praktische Beispiele

Seite 3: Wichtige Operatoren

Inhaltsverzeichnis

Auf der Basis des Beispiels geht es nun an die wichtigsten Operatoren:

Map: Der Map-Operator transformiert den Parameter jedes Events mit einer angegebenen Funktion und gibt ein Observable zurück, das die transformierten Werte enthält.

Der Map-Operator transformiert die Werte 1, 2 und 3 eines Observables in die Werte 10, 20 und 30 (Abb. 3).

(Bild: http://reactivex.io/documentation/operators/map.html)

Eine RxSwift-Implementierung dieses Operators sieht wie folgt aus:

func testMap() {
let observable = Observable.from([1, 2, 3])
observable
.map{value in value * 10}
.subscribe(onNext: {print($0)})
.disposed(by: disposeBag)
}

und führt zu folgender Ausgabe in der Konsole:

10
20
30

In der Praxis kommt der Operator zum Beispiel zum Einsatz, wenn nur eine Eigenschaft der emittierten Objekte von Interesse ist.

Scan: Dieser Operator arbeitet ebenfallsauf einem Observable. Bei seinem Aufruf ist eine Funktion zu übergeben, die zwei Argumente erhält. Das erste ist das Ergebnis des vorherigen Aufrufs und das zweite ist das Event des Observables. Für den ersten Aufruf des Operators ist ein Default-Wert anzugeben. Die Ergebnisse der Funktion werden wiederum als neues Observable ausgegeben.

Der [code]Scan[/code]-Operator summiert alle Werte des Observables und gibt jeweils den kumulierten Wert aus (Abb. 4).

(Bild: http://reactivex.io/documentation/operators/scan.html)

Eine RxSwift-Implementierung dieses Operators mit einer Funktion, die die Werte aller Events summiert, sieht wie folgt aus:

func testScan() {
let observable = Observable.from([1, 2, 3, 4, 5])
observable
.scan(0) {seed, value in seed + value}
.subscribe(onNext: {print($0)})
.disposed(by: disposeBag)
}

und führt zu folgender Ausgabe in der Konsole:

1 
3
6
10
15

In der Praxis wäre das gezeigte Beispiel auch das gängigste. Mit der Verwendung des Scan-Operators lässt sich stets die Summe aller Elemente des Streams ausgeben.

Filter: Auch dieser Operator arbeitet auf einem Observable. Er gibt eines zurück, das nur diejenigen Events des Input-Streams enthält, die die übergebene Prädikatsfunktion als wahr evaluiert.

Der Filter-Operator filtert alle Werte aus dem Observable, die größer als 10 sind (Abb. 5).

(Bild: http://reactivex.io/documentation/operators/filter.html)

Eine RxSwift-Implementierung dieses Operators sieht wie folgt aus:

func testFilter() {
let observable = Observable.from([2, 30, 22, 5, 60, 1])
observable
.filter {$0 > 10}
.subscribe(onNext: {print($0)})
.disposed(by: disposeBag)
}

und führt zu folgender Ausgabe in der Konsole:

30
22
60

Zip: Dieser Operator arbeitet auf mehreren Observables. Sobald er von jedem der Observables, auf denen er arbeitet, ein Event erhalten hat, kombiniert er sie und gibt sie als ein Event in seinem Ausgabe-Observable aus. Anschließend wartet er auf das zweite Event jedes Observables und so weiter.

Der Zip-Operator kombiniert die Werte von zwei Observables und erstellt ein neues, über das die neuen Werte emittiert werden (Abb. 6).

Eine RxSwift-Implementierung dieses Operators sieht wie folgt aus:

func testZip() {
let numbers = Observable.from([1, 2, 3, 4, 5])
let letters = Observable.from(["A", "B", "C", "D"])
Observable.zip(numbers, letters) { return ($0, $1) }
.subscribe(onNext: {print($0)})
.disposed(by: disposeBag)
}

und führt zu folgender Ausgabe in der Konsole:

(1, "A")
(2, "B")
(3, "C")
(4, "D")

Ein in der Praxis üblicher Anwendungsfall ist, dass man eine Aktion ausführen soll, sobald zwei oder mehr HTTP-Requests eine Antwort geliefert haben.

Wie im theoretischen Teil erwähnt, spezifiziert ReactiveX für nahezu jeden Anwendungsfall einen Operator. Nach der Implementierung der ersten Operatoren ist erkennbar, dass ihre Benennung äußerst deskriptiv ist. Hierbei handelt es sich um einen der größten Vorteile von RxSwift. Das Framework lässt asynchronen Code und reaktive Programmierung leserlich und wartbar werden.