Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
RxSwift:如何摆脱订阅事件和网络请求的回调地狱?_Swift_Rx Swift - Fatal编程技术网

RxSwift:如何摆脱订阅事件和网络请求的回调地狱?

RxSwift:如何摆脱订阅事件和网络请求的回调地狱?,swift,rx-swift,Swift,Rx Swift,RxSwift:如何摆脱订阅事件和网络请求的回调地狱 我是一个新手,这是我新公司的代码 下面的代码非常复杂 逻辑很简单。输出有一个requestCommand,它是PublishSubject。它用于执行一些刷新操作(一次又一次地请求网络) 地狱在里面。网络层Moya以RxSwift方式使用 RxSwift新手,我不知道如何很好地重构它 如何正确使用过滤器/映射/组合运算符 这是装有RxSwift的模型 import RxSwift import RxCocoa import RxDataSo

RxSwift:如何摆脱订阅事件和网络请求的回调地狱

我是一个新手,这是我新公司的代码

下面的代码非常复杂

逻辑很简单。输出有一个requestCommand,它是PublishSubject。它用于执行一些刷新操作(一次又一次地请求网络)

地狱在里面。网络层Moya以RxSwift方式使用

RxSwift新手,我不知道如何很好地重构它

如何正确使用过滤器/映射/组合运算符

这是装有RxSwift的模型


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
:每当任何可观察序列产生一个元素时,将指定的可观察序列合并为一个可观察元组序列

将两个不相关的事件组合在一起,做一些共同的事情是很好的

顺便说一句:我想了两天,不知道怎么解决。我 系统地列出并张贴在这里,过了一段时间,我想起来了 出去,有趣的经历