rxswift:如何获得Observable <any>导致Observable&lt; [Category]&gt;?的组合

时间:2016-12-06 14:45:33

标签: swift reactive-programming rx-swift reactivex reactive

我的方法有些疑惑。我有两种类型的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中做到这一点?

谢谢

1 个答案:

答案 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]
}
  • [1]:我们将一个房子数组映射到一个Observable<Family>
  • 数组
  • [2]: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) }
}