RxSwift, wie kann ich verschiedene Observable verketten?

8

Ich bin immer noch Anfänger in der reaktiven Programmierung und RxSwift im Allgemeinen. Ich möchte zwei verschiedene Operationen verketten. In meinem Fall möchte ich einfach eine Zip-Datei von einem Webserver herunterladen und dann lokal entpacken. Ich möchte auch gleichzeitig den Fortschritt der heruntergeladenen Dateien anzeigen. Also fing ich an, das erste Observable zu erstellen:

%Vor%

Danach erstelle ich eine ähnliche Funktion für das unzip

%Vor%

Vorerst habe ich diese Logik auf der "Model-Ebene ansehen", also lade ich- & gt; auf abgeschlossene- & gt; entpacken

Was ich will, ist, die beiden Observable in einem zu kombinieren, um den Download zuerst durchzuführen, und dann die fertige Datei zu entpacken. Gibt es eine Möglichkeit, dies zu tun?

    
Punty 11.03.2016, 09:25
quelle

2 Antworten

2

Der Operator Concat benötigt den gleichen Datentyp

Tatsächlich können Sie mit dem Operator concat die Reihenfolge der Observablen erzwingen. Ein Problem bei der Verwendung von concat ist jedoch, dass der Operator concat den gleichen generischen Typ wie Observable s benötigt.

%Vor% Mit

FlatMap können Sie eine Sequenz von Observable s

verketten

Hier ist ein Beispiel.

%Vor%

Beachten Sie, dass getRequestReadHTML vom Typ Observable<String> ist, während die Funktion getTagsFromHtml vom Typ Observable<Tag> ist.

Die Verwendung mehrerer flatMaps kann die Emissionsfrequenz erhöhen

Seien Sie jedoch vorsichtig, weil der Operator flatMap ein Array (z. B. [1,2,3]) oder eine Sequenz (z. B. ein Observable) verwendet und alle Elemente als Emission ausgibt. Deshalb ist es bekannt, eine Transformation von 1...n zu erzeugen.

Wenn Sie ein Observable wie einen Netzwerkaufruf definiert haben und sicher sind, dass es nur eine Emission geben wird, werden Sie keine Probleme haben, da seine Transformation ein 1...1 ist (d. h. ein Observable zu einem NSData). Großartig!

Wenn Ihr Observable jedoch mehrere Emissionen aufweist, sollten Sie sehr vorsichtig sein, da verkettete flatMap -Operatoren dazu führen, dass die Emissionen exponentiell (?) ansteigen.

Ein konkretes Beispiel wäre, wenn das erste Observable 3 Emissionen emittiert, transformiert der Operator flatMap 1...n mit n = 2, was bedeutet, dass es nun insgesamt 6 Emissionen gibt. Ein anderer flatMap-Operator könnte 1...n wieder umwandeln, wobei n = 2 ist, was bedeutet, dass es jetzt insgesamt 12 Emissionen gibt. Überprüfen Sie, ob dies das erwartete Verhalten ist.

    
iwillnot 15.11.2016 15:43
quelle
1

Sie können den Operator concat verwenden, um diese beiden Observables zu verketten. Das resultierende Observable sendet next -Werte vom ersten und nach Abschluss vom zweiten.

Es gibt eine Einschränkung: Sie erhalten Fortschrittswerte von 0.0 bis 1.0 von rx_download und dann beginnt der Fortschritt von rx_unzip mit 0.0. Dies kann für den Benutzer verwirrend sein, wenn Sie den Fortschritt einer einzelnen Fortschrittsanzeige anzeigen möchten.

Ein möglicher Ansatz wäre es, ein Label zu zeigen, das beschreibt, was mit der Fortschrittsanzeige passiert. Sie können map je Observable auf ein Tupel mit dem Fortschrittswert und dem Beschreibungstext setzen und dann concat verwenden. Es kann so aussehen:

%Vor%

Natürlich gibt es viele mögliche Lösungen, aber das ist eher ein Designproblem als ein Codieren.

    
Michał Ciuba 11.03.2016 11:06
quelle

Tags und Links