Fer*_*ney 2 ios rx-swift reactivex
我目前遇到使用RxSwift Observables时执行多个网络请求的问题.我知道如果一个人创建了一个冷可观察对象并且它有多个观察者,那么observable将在每次订阅时执行它的块.
我已经尝试创建一个执行网络请求的共享订阅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<String> { // 2
let serviceStatusObseravble = self.getServiceStatusObservable()
let filtered = serviceStatusObseravble.filter { status in
return status != "Loading"
}
return filtered
}
public var serviceExecuting: Observable<Bool> { // 3
return self.serviceStatus.map { status in
return status == "Loading"
}
.startWith(false)
}
private let buttonTapped: Observable<Void>
init(buttonTapped: Observable<Void>) {
self.buttonTapped = buttonTapped
}
private func getServiceStatusObservable() -> Observable<String> {
return self.buttonTapped.flatMap { _ -> Observable<String> in
return self.createServiceStatusObservable()
}
}
private func createServiceStatusObservable() -> Observable<String> {
return Observable.create({ (observer) -> Disposable in
someAsyncServiceRequest() { result }
observer.onNext(result)
})
return NopDisposable.instance
})
.startWith("Loading")
.shareReplay(1)
}
Run Code Online (Sandbox Code Playgroud)
编辑:
基于下面的对话,以下是我正在寻找的......
我需要对从getServiceStatusObservable()方法返回的Observable应用share()函数,而不是从createServiceStatusObservable()方法返回的Observable.有多个观察者被添加到这个观察者以检查当前状态.这意味着执行网络请求的可观察对象被执行了N次(N是观察者的数量).现在每次点击按钮,网络请求都会执行一次,这就是我需要的.
private func getServiceStatusObservable() -> Observable<String> {
return self.buttonTapped.flatMap { _ -> Observable<String> in
return self.createServiceStatusObservable()
}.share()
}
Run Code Online (Sandbox Code Playgroud)
.shareReplay(1)将仅适用于一个可观察的实例.在createServiceStatusObservable()共享行为中创建它时,只会影响此函数返回的一个值.
class ViewModel {
let serviceStatusObservable: Observable<String>
init(buttonTapped: Observable<Void>) {
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<String> {
return self.buttonTapped.flatMap { [weak self] _ -> Observable<String> in
return self.serviceStatusObservable
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于这个版本,serviceStatusObservable只创建一次,因此它的副作用将在每次使用时共享,因为它是相同的实例.