2016-12-06 4 views
0

Ich habe einige Zweifel in meinem Ansatz. Ich habe zwei Arten von Observable:rxswift: wie erhält man das Observable <Any> Ergebnis in einer Kombination von Observable <[Category]>?

//I can fetch from the server the houses and save them in the database 
func houses() -> Observable<[House]> 

//Given a houseId, I can fetch it's details and save them in the database 
func houseDetail(id: Int) -> Observable<Family> 

Ich mag würde ein beobachtbares tun, die zuerst alle Häuser holen, und dann die Familien holen. Was ich tat, ist so etwas wie die:

//I am an observable which, when I complete, all data are saved 
func fetchAllHousesAndFamily() -> Observable<Any> { 
    var allHousesObservables: [Observable] = [] 
    for house in houses { 
    allHousesObservables.append(houseDetail(house.id)) 
    } 
    return Observable.combineLatest(allHousesObservables) 
} 

Aber dies ... es scheint nicht reaktiver Stil mir zu sein, und es scheint wie ein Hack, weil ich weiß nicht genug über rx Betreiber.

Haben Sie den richtigen Weg, es in der rxworld zu tun?

Danke

+0

Ich denke, dass Ihre Aufgabe, eine elegantere Lösung. Kannst du Beispielcode mit deiner Aufgabe auf einem Github teilen? Ich möchte dir helfen. – Svyatoslav

Antwort

3

Um alle Familie aus dem Ergebnis der houses zu bekommen, werden Sie den flatMap Operator verwenden. flatMap akzeptiert einen Verschluss mit Unterschrift T -> Observable<U>, so in unserem speziellen Beispiel wird es eine Funktion des Typs [House] -> Observable<Family> sein.

houses().flatMap { houses in 
    let details: [Observable<Family>] = houses.map { houseDetail($0.id) } // [1] 

    return Observable.from(details).merge() // [2] 
} 
  • [1]: Wir Abbilden ein Array von Haus zu einem Array von Observable<Family>.
  • [2]: from(_:) konvertiert [Observable<Family>] zu Observable<Observable<Family>>. merge() verwandeln sie dann zu Observable<Family>

Wir haben jetzt eine beobachtbare, dass man nächstes Ereignis für jedes Haus mit seiner Familie Details emittieren.

Wenn wir um den House Wert zu halten bevorzugen würden, könnten wir einfach wieder Karte in der ersten Zeile, etwa so:

let details: [Observable<(House, Family)>] = house.map { house in 
    houseDetail(house.id).map { (house, $0) } 
} 
Verwandte Themen