2015-10-31 9 views
6

Wciąż jestem reaktywnym początkującym i szukam pomocy.Łącząc dwa możliwe do zaobserwowania <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 

} 

Powyższy to co myślę, że chcę ... Początkowe funkcje doA() i doB() sieć okład wzywa więc będą zarówno emitować jeden sygnał, a następnie Complete (lub Error bez emisji jakichkolwiek Next zdarzenia). Jeśli doA() dopełnia ale błędy doB(), chcę doIt() emitować .BFailed, a następnie zakończyć.

Czuję, że powinienem używać zip lub combineLatest, ale nie jestem pewien, jak się dowiedzieć, która sekwencja się nie powiodła, jeśli to zrobię. Jestem też całkiem pewien, że catchError jest częścią rozwiązania, ale nie jestem pewien, gdzie dokładnie to umieścić.

-

Jak myślę o tym, że jestem w porządku z rozmowy dzieje sekwencyjnie. To może być nawet lepiej ...

IE:

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

Dzięki za wszelką pomoc.

Odpowiedz

0

Przepraszam, że nie znam składni szybkiej, więc piszę odpowiedź w języku C#. Kod powinien być bezpośrednio tłumaczony.

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); 

Zasadniczo operator .Materialize() włącza OnNext, OnError i OnCompleted powiadomienia o zauważalny typu T do OnNext powiadomień dla zauważalny typu Notification<T>. Możesz następnie .Zip(...) te i sprawdzić swoje wymagane warunki.

+0

Hmm ... Dzięki za odpowiedź, ale RxSwift nie ma metody materializacji. Przynajmniej jeszcze nie. –

0

Wydaje mi się, że znalazłem odpowiedź samemu ... Oczywiście to rozwiązanie nie czeka na pełną wiadomość od doA() lub doB(). Zamiast tego emituje obiekt Result w sygnale onNext, ale ponieważ są to połączenia sieciowe, i tak pozostanie tylko jedenNastępny przed zakończeniem. Może myślenie, że muszę czekać na komplet, było dla mnie trudne do zrozumienia.

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

wierzę .flatMapLatest() jest to, czego szukasz, łańcuchowym zaobserwowania swoich żądań.

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) 

A tutaj jest .flatMapLatest() doktor w RxSwift.

Projekty każdy element obserwowanej sekwencji do nowej sekwencji obserwowalnych sekwencji i przekształca zaobserwowania sekwencję zaobserwowania sekwencji do możliwego do zaobserwowania sekwencji wytwarzania tylko wartości z ostatniego obserwowanej sekwencji. Jest to połączenie operatora map + switchLatest.

Powiązane problemy