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?
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.
Observable
s Hier ist ein Beispiel.
%Vor% Beachten Sie, dass getRequestReadHTML
vom Typ Observable<String>
ist, während die Funktion getTagsFromHtml
vom Typ Observable<Tag>
ist.
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.
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:
Natürlich gibt es viele mögliche Lösungen, aber das ist eher ein Designproblem als ein Codieren.