/ / rxswift: Wie erhält man das Observable <Any>, was zu einer Kombination von Observable <[Category]> führt? - schnelle, reaktive Programmierung, rx-swift, reactivex, reaktiv

rxswift: Wie erhält man das Observable <Any>, was zu einer Kombination von Observable <[Category]> führt? - schnelle, reaktive Programmierung, rx-swift, reactivex, reaktiv

Ich habe einige Zweifel an meiner Herangehensweise. Ich habe zwei Arten von Observablen:

//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 möchte einen Observablen machen, der zuerst alle Häuser holt und dann die Familien holt. Was ich getan habe, ist so etwas:

//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 das scheint ... es scheint nicht zu sein reaktiver Stil zu mir, und es scheint wie ein Hack, weil ich nicht genug über RX-Betreiber weiß.

Hast du den richtigen Weg in der rxworld?

Vielen Dank

Antworten:

3 für die Antwort № 1

Um die ganze Familie von dem Ergebnis zu erhalten houses, wirst du das benutzen wollen flatMap Operator. flatMap akzeptiert einen Verschluss mit Unterschrift T -> Observable<U>In unserem speziellen Beispiel wird es eine Funktion des Typs sein [House] -> Observable<Family>.

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

return Observable.from(details).merge() // [2]
}
  • [1]: Wir ordnen eine Reihe von Häusern einer Reihe von Observable<Family>.
  • [2]: from(_:) konvertiert [Observable<Family>] zu Observable<Observable<Family>>. merge() dann verwandle es in Observable<Family>

Wir haben jetzt ein Observable, das für jedes Haus mit seinen Familiendetails ein nächstes Ereignis aussendet.

Wenn wir es vorziehen würden, die House Wert herum, könnten wir einfach wieder auf die erste Zeile mappen, so:

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