2016-07-19 6 views
1

ich RxSwift für das Caching in meinem iOS-App und hat ein Stück Code wie folgt bin mit:ReactiveX RxSwift erhält erste nicht Fehler von Concat von Observablen

let observable = Observable.of(cache.getItem(itemID), network.getItem(itemID)).concat().take(1) 

observable.subscribeNext // and do some stuff 

Ich habe die cache.getItem Methode ein onError zu tun, wenn es hat kein Wert, und möchte es dann auf das Netzwerk verschieben, aber aus irgendeinem Grund wird das Netzwerk nie ausgeführt. Ich nehme an, weil ich Take (1) verwende, aber ich möchte, dass das Observable aufhört zu emittieren, sobald der Cache etwas findet (oder mit dem Netzwerk fortfahren, wenn dies nicht der Fall ist).

Irgendwelche Ideen, wie man das macht?

Ich habe this Guide verfolgt, aber er geht nicht ins Detail über das Verhalten seines Caches, wenn es etwas nicht finden kann.

Antwort

2

Sie sollten .Error nicht so verwenden. Das ist nicht wirklich ein Fehlerfall. Es ist einfach nichts im Cache. Das ist eine häufige Situation. Nichts ist "falsch" ausgefallen. Senden Sie stattdessen einfach ein .Completed Ereignis.

Was, warum Ihr Code nicht funktioniert, dann ist es, weil ein Fehler von einem in der concat enthalten Observable kommen wird einen Fehler in der letzten concatObservable werden. Die Sache mit Rx zu erinnern ist, dass, sobald es ein .Completed Ereignis oder (in Ihrem Fall) ein .Error Ereignis ist, das ist es, es ist vorbei, nicht mehr .Next Ereignisse (oder irgendwelche Ereignisse).

Also statt, wenn Sie .Completed verwenden, würde Ihr Code arbeiten, wie so:

class Cache { 
    func getItem(itemID: Int) -> Observable<Item> { 
     return Observable<Item>.create { observer in 
      // if not found... 
      observer.onCompleted() // you would of course really try to get it 
            // from the cache first. 
      return NopDisposable.instance 
     } 
    } 
} 

class Network { 
    func getItemN(itemID: Int) -> Observable<Item> { 
     return Observable<Item>.create { observer in 
      // get some `item` from the network and then.. 
      observer.onNext(item) 
      return NopDisposable.instance 
     } 
    } 
} 

let observable = Observable.of(cache.getItem(itemID), network.getItem(itemID)).concat().take(1) 

observable.subscribeNext { item in 
    print(item) 
} 
+1

Awesome, dank dude! Gute Erklärung und funktioniert perfekt – Josh

+0

Direkt dran, Spaß mit Rx! – solidcell

Verwandte Themen