我需要从网络请求不同类型的模型,然后将它们组合成一个模型。 如何链接多个可观察对象并返回另一个可观察对象?
我有类似的东西:
func fetchDevices() -> Observable<DataResponse<[DeviceModel]>>
func fetchRooms() -> Observable<DataResponse<[RoomModel]>>
func fetchSections() -> Observable<DataResponse<[SectionModel]>>
我需要做类似的事情:
func fetchAll() -> Observable<(AllModels, Error)> {
fetchSections()
// Then if sections is ok I need to fetch rooms
fetchRooms()
// Then - fetch devices
fetchDevices()
// And if everything is ok create AllModels class and return it
// Or return error if any request fails
return AllModels(sections: sections, rooms: rooms, devices:devices)
}
如何使用RxSwift实现它?我阅读了文档和示例,但了解如何链接具有相同类型的observable
答案 0 :(得分:4)
尝试combineLatest
运算符。您可以组合多个可观察量:
let data = Observable.combineLatest(fetchDevices, fetchRooms, fetchSections)
{ devices, rooms, sections in
return AllModels(sections: sections, rooms: rooms, devices:devices)
}
.distinctUntilChanged()
.shareReplay(1)
然后,您订阅了它:
data.subscribe(onNext: {models in
// do something with your AllModels object
})
.disposed(by: bag)
答案 1 :(得分:0)
我认为获取模型的方法应该驻留在ViewModel中,并且事件应该等待开始完全调用它们,否则它们将无法开始运行。
假设有一个按钮调用你的三种方法,并且如果函数调用成功则会再启用一个按钮。
考虑ViewController中的ViewModel。
let viewModel = ViewModel()
在ViewModel中,声明这样的抽象I / O事件,
struct Input {
buttonTap: Driver<Void>
}
struct Output {
canProcessNext: Driver<Bool>
}
然后,您可以通过在ViewModel中创建这样的函数,将输入显式转换为输出。
func transform(input: Input) -> Output {
// TODO: transform your button tap event into fetch result.
}
在viewDidLoad,
let output = viewModel.transform(input: yourButton.rx.tap.asDriver())
output.drive(nextButton.rx.isEnabled).disposed(by: disposeBag)
现在一切都准备就绪,但结合了你的三种方法 - 将它们放在ViewModel中。
func fetchDevices() -> Observable<DataResponse<[DeviceModel]>>
func fetchRooms() -> Observable<DataResponse<[RoomModel]>>
func fetchSections() -> Observable<DataResponse<[SectionModel]>>
让我们完成&#39; TODO&#39;
let result = input.buttonTap.withLatestFrom(
Observable.combineLatest(fetchDevices(), fetchRooms(), fetchSections()) { devices, rooms, sections in
// do your job with response data and refine final result to continue
return result
}.asDriver(onErrorJustReturn: true))
return Output(canProcessNext: result)
我不仅要写它只是让它工作,还要考虑整个设计的应用程序。将所有内容放在ViewController中是不可取的,特别是使用Rx设计。我认为将VC和VC分开是一个不错的选择。 ViewModel登录以供将来维护。看看this sample,我认为它可能对你有所帮助。