0

我对自己的方法有些怀疑。我有两种类型的 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)
}

但这对于……对我来说似乎不是反应式风格,而且这似乎是一种 hack,因为我对 rx 运算符了解不足。

您在 rxworld 中有正确的方法吗?

谢谢

4

1 回答 1

3

要从 的结果中获取所有家庭houses,您将需要使用flatMap运算符。flatMap接受带有签名的闭包T -> Observable<U>,因此,在我们的具体示例中,它将是 type 的函数[House] -> Observable<Family>

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

  return Observable.from(details).merge() // [2]
}
  • [1]:我们正在将一个 house 数组映射到一个Observable<Family>.
  • [2]:from(_:)转换[Observable<Family>]Observable<Observable<Family>>. merge()然后将其转换为Observable<Family>

我们现在有一个 observable,它将为每所房子发出一个带有其家庭详细信息的下一个事件。

如果我们希望保留该House值,我们可以简单地在第一行再次映射,如下所示:

let details: [Observable<(House, Family)>] = house.map { house in 
  houseDetail(house.id).map { (house, $0) }
}
于 2016-12-06T15:36:06.873 回答