RxSwift:如何摆脱订阅事件和网络请求的回调地狱?
RxSwift:如何摆脱订阅事件和网络请求的回调地狱 我是一个新手,这是我新公司的代码 下面的代码非常复杂 逻辑很简单。输出有一个requestCommand,它是PublishSubject。它用于执行一些刷新操作(一次又一次地请求网络) 地狱在里面。网络层Moya以RxSwift方式使用 RxSwift新手,我不知道如何很好地重构它 如何正确使用过滤器/映射/组合运算符 这是装有RxSwift的模型RxSwift:如何摆脱订阅事件和网络请求的回调地狱?,swift,rx-swift,Swift,Rx Swift,RxSwift:如何摆脱订阅事件和网络请求的回调地狱 我是一个新手,这是我新公司的代码 下面的代码非常复杂 逻辑很简单。输出有一个requestCommand,它是PublishSubject。它用于执行一些刷新操作(一次又一次地请求网络) 地狱在里面。网络层Moya以RxSwift方式使用 RxSwift新手,我不知道如何很好地重构它 如何正确使用过滤器/映射/组合运算符 这是装有RxSwift的模型 import RxSwift import RxCocoa import RxDataSo
import RxSwift
import RxCocoa
import RxDataSources
import MJRefresh
import Moya
import MoyaMapper
// this is the Moya Network Provider
let Provider = MoyaProvider<Router>(endpointClosure: EndpointClosure, requestClosure: requestClosure, plugins: [networkPlugin, MoyaMapperPlugin(NetParameter())], trackInflights: false)
struct BoutiqueOutput: OutputRefreshProtocol {
var refreshStatus = Variable<RefreshStatus>(.none)
let sections: Driver<[CategoryLeftSection]>
let requestCommand = PublishSubject<Bool>()
init(sections: Driver<[CategoryLeftSection]>) {
self.sections = sections
}
}
class CategoryViewModel: NSObject {
let vmDatas = Variable<[ParentItem]>([])
func transform() -> BoutiqueOutput {
let tempSections = vmDatas.asObservable().map({ (sections) -> [CategoryLeftSection] in
return [CategoryLeftSection(items: sections)]
}).asDriver(onErrorJustReturn: [])
let output = BoutiqueOutput(sections: tempSections)
output.requestCommand.subscribe(onNext:{[weak self] _ in
guard let self = self else { return }
Provider.rx.cacheRequest(.baseUIData).subscribe( onNext:{ result in
// do some UI
if result.statusCode == 200 || result.statusCode == 230 {
// do something business
}
}).disposed(by: self.rx.disposeBag)
}).disposed(by: rx.disposeBag)
return output
}
}
导入RxSwift
进口RxCocoa
导入RxDataSources
导入MJRefresh
进口莫亚
进口MoyaMapper
//这是莫亚网络提供商
let Provider=MoyaProvider(endpointClosure:endpointClosure,requestClosure:requestClosure,plugins:[networkPlugin,MoyaMapperPlugin(NetParameter())],trackinflight:false)
结构输出:OutputRefreshProtocol{
变量refreshStatus=变量(.none)
让我们看看:驱动程序
让requestCommand=PublishSubject()
初始化(部分:驱动程序){
self.sections=节
}
}
类CategoryViewModel:NSObject{
让vmDatas=变量([])
func transform()->输出{
让tempSections=vmDatas.asObservable().map({(sections)->[CategoryLeftSection]位于
返回[类别段(项目:段)]
}).asDriver(onErrorJustReturn:[])
让输出=输出(节:tempSections)
output.requestCommand.subscribe(onNext:{[weak self]\uIn
guard let self=self-else{return}
Provider.rx.cacheRequest(.baseUIData).subscribe(onNext:{结果为
//做一些UI
如果result.statusCode==200 | | result.statusCode==230{
//做点生意
}
}).处置(由:self.rx.disposeBag)
}).处置(由:rx.disposeBag)
返回输出
}
}
这就是模型的应用方式
private var vmOutput: BoutiqueOutput?
override func viewDidLoad() {
super.viewDidLoad()
self.vmOutput = viewModel.transform()
boundTableViewData()
// ...
}
private func boundTableViewData() {
let dataSource = RxTableViewSectionedReloadDataSource<CategoryLeftSection>( configureCell: { [weak self] ds, tv, ip, item in
// ...
}
vmOutput!.sections.asDriver().drive(self.leftMenuTableView.rx.items(dataSource: dataSource)).disposed(by: rx.disposeBag)
// ...
vmOutput!.requestCommand.onNext(true)
}
private func requestErrorRefresh() {
// ...
if isNetworkConnect {
boundTableViewData()
vmOutput!.requestCommand.onNext(true)
}
}
private func noNetworkRefresh() {
// ...
if isNetworkConnect {
boundTableViewData()
vmOutput!.requestCommand.onNext(true)
}
}
private var vmOutput:输出?
重写func viewDidLoad(){
super.viewDidLoad()
self.vmOutput=viewModel.transform()
boundTableViewData()
// ...
}
私有函数boundTableViewData(){
让dataSource=RxTableViewSectionedReloadDataSource(configureCell:{[weak self]ds,tv,ip,中的项
// ...
}
vmOutput!.sections.asDriver().drive(self.leftMenuTableView.rx.items(dataSource:dataSource)).disposed(by:rx.disposeBag)
// ...
vmOutput!.requestCommand.onNext(true)
}
private func requestErrorRefresh(){
// ...
如果是网络连接{
boundTableViewData()
vmOutput!.requestCommand.onNext(true)
}
}
private func noNetworkRefresh(){
// ...
如果是网络连接{
boundTableViewData()
vmOutput!.requestCommand.onNext(true)
}
}
我使用combinelateest
操作符来解决这个问题
代码如下:
let output = BoutiqueOutput(sections: temp_sections)
Observable.combineLatest(output.requestCommand, Provider.rx.cacheRequest(.baseUIData)).subscribe({ [weak self] ( result: Event<(Bool, Response)>) in
guard let self = self else { return }
switch result{
case .next(let response):
// do some UI
if result.statusCode == 200 || result.statusCode == 230 {
// do something business
}
default:
break
}
}).disposed(by: rx.disposeBag)
let output=output(区段:临时区段)
Observable.CombineTest(output.requestCommand,Provider.rx.cacheRequest(.baseUIData)).subscribe({[weak self](结果:事件)在
guard let self=self-else{return}
切换结果{
案例。下一步(让我们回答):
//做一些UI
如果result.statusCode==200 | | result.statusCode==230{
//做点生意
}
违约:
打破
}
}).处置(由:rx.disposeBag)
combinelateest
:每当任何可观察序列产生一个元素时,将指定的可观察序列合并为一个可观察元组序列
将两个不相关的事件组合在一起,做一些共同的事情是很好的
顺便说一句:我想了两天,不知道怎么解决。我
系统地列出并张贴在这里,过了一段时间,我想起来了
出去,有趣的经历