链接不同类型的 RxSwift observable
Chaining RxSwift observable with different type
我需要从网络请求不同类型的模型,然后将它们组合成一个模型。
如何链接多个可观察对象和 return 另一个可观察对象?
我有类似的东西:
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实现?我阅读了文档和示例,但了解如何将相同类型的可观察对象链接起来
尝试 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)
我认为获取模型的方法应该驻留在 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]>>
让我们完成'TODO'
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 和 ViewModel 登录分开以备将来维护是个不错的选择。看看this sample,我想它可能对你有帮助。
我需要从网络请求不同类型的模型,然后将它们组合成一个模型。 如何链接多个可观察对象和 return 另一个可观察对象?
我有类似的东西:
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实现?我阅读了文档和示例,但了解如何将相同类型的可观察对象链接起来
尝试 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)
我认为获取模型的方法应该驻留在 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]>>
让我们完成'TODO'
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 和 ViewModel 登录分开以备将来维护是个不错的选择。看看this sample,我想它可能对你有帮助。