2015-10-31 14 views
6

Ich bin immer noch ein reaktiver Neuling und ich bin auf der Suche nach Hilfe.Kombinieren zwei Observable <Void> s

func doA() -> Observable<Void> 
func doB() -> Observable<Void> 

enum Result { 
    case Success 
    case BFailed 
} 

func doIt() -> Observable<Result> { 

    // start both doA and doB. 
    // If both complete then emit .Success and complete 
    // If doA completes, but doB errors emit .BFailed and complete 
    // If both error then error 

} 

Die oben ist, was ich glaube, ich will ... Die ersten Funktionen doA() und doB() Wrap-Netzwerk ruft, so dass sie beide ein Signal aussenden und dann Complete (oder Error ohne Next Ereignisse zu emittieren.) Wenn doA() abgeschlossen ist aber doB() Fehler, ich möchte doIt() emittieren und dann abschließen.

Es fühlt sich an, als ob ich zip oder combineLatest verwenden sollte, aber ich weiß nicht, wie ich wissen soll, welche Sequenz fehlgeschlagen ist, wenn ich das tue. Ich bin mir auch ziemlich sicher, dass catchError Teil der Lösung ist, aber ich bin mir nicht sicher, wo genau es hingehört.

-

Als ich darüber denke, ich bin in Ordnung mit den Anrufen nacheinander passiert. Das könnte noch besser sein ...

IE:

Start doA() 
    if it completes start doB() 
     if it completes emit .Success 
     else emit .BFailed. 
    else forward the error. 

Vielen Dank für jede Hilfe.

Antwort

0

Ich entschuldige mich, dass ich die Syntax für swift nicht kenne, also schreibe ich die Antwort in C#. Der Code sollte direkt übersetzbar sein.

var query = 
    doA 
     .Materialize() 
     .Zip(doB.Materialize(), (ma, mb) => new { ma, mb }) 
     .Select(x => 
      x.ma.Kind == NotificationKind.OnError 
      || x.mb.Kind == NotificationKind.OnError 
       ? Result.BFailed 
       : Result.Success); 

Grundsätzlich ist der .Materialize() Bediener dreht die OnNext, OnError und OnCompleted Benachrichtigungen für eine beobachtbare des Typs T in OnNext Benachrichtigungen für eine beobachtbare des Typs Notification<T>. Sie können dann .Zip(...) diese und überprüfen Sie Ihre erforderlichen Bedingungen.

+0

Hmm ... Danke für die Antwort, aber RxSwift hat nicht die materialisierte Methode. Zumindest jetzt noch nicht. –

0

Ich habe selbst eine Antwort gefunden ... Zugegeben, diese Lösung wartet nicht auf die vollständige Nachricht von doA() oder doB(). Stattdessen gibt es das Result-Objekt auf dem onNext-Signal aus, aber da es sich um Netzwerkaufrufe handelt, wird nur eine onNext vor dem Abschluss vorhanden sein. Vielleicht zu denken, dass ich auf das Vollständige warten musste, war das, was es für mich schwer machte zu verstehen.

func doIt() -> Observable<Result> { 
    return doA().flatMap { 
     return doB().map { 
      .Success 
     } 
     .catchError { 
      just(.BFailed) 
     } 
    } 
} 
1

Ich glaube .flatMapLatest() ist das, was Sie suchen, Ihre beobachtbare Anfragen Verkettungs.

doFirst() 
.flatMapLatest({ [weak self] (firstResult) -> Observable<Result> in 
    // Assuming this doesn't fail and returns result on main scheduler, 
    // otherwise `catchError` and `observeOn(MainScheduler.instance)` can be used to correct this 
    // ... 
    // do something with result #1 
    // ... 
    return self?.doSecond() 
}).subscribeNext { [weak self] (secondResult) -> Void in 
    // ... 
    // do something with result #2 
    // ... 
}.addDisposableTo(disposeBag) 

Und hier ist .flatMapLatest() doc in RxSwift.

Projiziert jedes Element einer beobachtbaren Sequenz in eine neue Sequenz beobachtbarer Sequenzen transformiert und dann eine beobachtbare Sequenz beobachtbarer Sequenzen in einer beobachtbaren Sequenzwerte Herstellung nur aus der letzten beobachtbaren Sequenz. Es ist eine Kombination von map + switchLatest Operator.