我的方法有些疑惑。我有两种类型的Observable:
//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>
我想做一个Observable,首先获取所有房屋,然后取出这些家庭。我做的是这样的:
//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)
}
但这对......来说似乎不是反应式,而且它看起来像是一个黑客,因为我对rx运营商不够了解。< / p>
你有没有正确的方法在rxworld中做到这一点?
谢谢
答案 0 :(得分:3)
要从houses
的结果中获取所有家庭,您需要使用flatMap
运算符。 flatMap
接受带有签名T -> Observable<U>
的闭包,因此,在我们的具体示例中,它将是[House] -> Observable<Family>
类型的函数。
houses().flatMap { houses in
let details: [Observable<Family>] = houses.map { houseDetail($0.id) } // [1]
return Observable.from(details).merge() // [2]
}
Observable<Family>
。from(_:)
将[Observable<Family>]
转换为Observable<Observable<Family>>
。 merge()
然后将其转换为Observable<Family>
我们现在有一个可观察物,它会为每个房子发出一个下一个事件及其家庭细节。
如果我们希望保持House
值,我们可以在第一行再次映射,如下所示:
let details: [Observable<(House, Family)>] = house.map { house in
houseDetail(house.id).map { (house, $0) }
}