我目前遇到使用RxSwift Observables时执行多个网络请求的问题.我知道如果一个人创建了一个冷可观察对象并且它有多个观察者,那么observable将在每次订阅时执行它的块.
我已经尝试创建一个执行网络请求的共享订阅observable,并且会通知多个订阅者结果.以下是我的尝试.
事件顺序
使用uibutton的tap事件创建视图模型
在视图模型上将serviceStatus Observable创建为公共属性.此Observable从buttonTapped Observable映射.然后它过滤掉"正在加载"状态.返回的Observable在其上执行了shareReplay(1)以返回共享订阅.
在视图模型上将serviceExecuting Observable创建为公共属性.此observable是从serviceStatus Observable映射的.如果状态为"正在加载",它将返回true
将uilabel绑定到serviceStatus Observable
将活动指示符绑定到serviceExecuting Observable.
当点击按钮时,服务请求被执行三次,我希望它只执行一次.有什么突出的不正确吗?
码
class ViewController { let disposeBag = DisposeBag() var button: UIButton! var resultLabel: UILabel! var activityIndicator: UIActivityIndicator! lazy var viewModel = { // 1 return ViewModel(buttonTapped: self.button.rx.tap.asObservable()) } override func viewDidLoad() { super.viewDidLoad() self.viewModel.serviceStatus.bindTo(self.resultLabel.rx_text).addDispsoableTo(disposeBag) // 4 self.viewModel.serviceExecuting.bindTo(self.activityIndicator.rx_animating).addDispsoableTo(disposeBag) // 5 } } class ViewModel { public var serviceStatus: Observable{ // 2 let serviceStatusObseravble = self.getServiceStatusObservable() let filtered = serviceStatusObseravble.filter { status in return status != "Loading" } return filtered } public var serviceExecuting: Observable { // 3 return self.serviceStatus.map { status in return status == "Loading" } .startWith(false) } private let buttonTapped: Observable init(buttonTapped: Observable ) { self.buttonTapped = buttonTapped } private func getServiceStatusObservable() -> Observable { return self.buttonTapped.flatMap { _ -> Observable in return self.createServiceStatusObservable() } } private func createServiceStatusObservable() -> Observable { return Observable.create({ (observer) -> Disposable in someAsyncServiceRequest() { result } observer.onNext(result) }) return NopDisposable.instance }) .startWith("Loading") .shareReplay(1) }
编辑:
基于下面的对话,以下是我正在寻找的......
我需要对从getServiceStatusObservable()方法返回的Observable应用share()函数,而不是从createServiceStatusObservable()方法返回的Observable.有多个观察者被添加到这个观察者以检查当前状态.这意味着执行网络请求的可观察对象被执行了N次(N是观察者的数量).现在每次点击按钮,网络请求都会执行一次,这就是我需要的.
private func getServiceStatusObservable() -> Observable{ return self.buttonTapped.flatMap { _ -> Observable in return self.createServiceStatusObservable() }.share() }
tomahh.. 5
.shareReplay(1)
将仅适用于一个可观察的实例.在createServiceStatusObservable()
共享行为中创建它时,只会影响此函数返回的一个值.
class ViewModel { let serviceStatusObservable: Observableinit(buttonTapped: Observable ) { self.buttonTapped = buttonTapped self.serviceStatusObservable = Observable.create({ (observer) -> Disposable in someAsyncServiceRequest() { result in observer.onNext(result) } return NopDisposable.instance }) .startWith("Loading") .shareReplay(1) } private func getServiceStatusObservable() -> Observable { return self.buttonTapped.flatMap { [weak self] _ -> Observable in return self.serviceStatusObservable } } }
对于这个版本,serviceStatusObservable
只创建一次,因此它的副作用将在每次使用时共享,因为它是相同的实例.
.shareReplay(1)
将仅适用于一个可观察的实例.在createServiceStatusObservable()
共享行为中创建它时,只会影响此函数返回的一个值.
class ViewModel { let serviceStatusObservable: Observableinit(buttonTapped: Observable ) { self.buttonTapped = buttonTapped self.serviceStatusObservable = Observable.create({ (observer) -> Disposable in someAsyncServiceRequest() { result in observer.onNext(result) } return NopDisposable.instance }) .startWith("Loading") .shareReplay(1) } private func getServiceStatusObservable() -> Observable { return self.buttonTapped.flatMap { [weak self] _ -> Observable in return self.serviceStatusObservable } } }
对于这个版本,serviceStatusObservable
只创建一次,因此它的副作用将在每次使用时共享,因为它是相同的实例.