我目前在使用RxSwift Observable时执行多个网络请求时遇到问题。我知道如果一个人创建了一个冷可观察对象并且它有多个观察者,那么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)
}
修改
根据下面的对话,我正在寻找以下内容......
我需要对从getServiceStatusObservable()方法返回的Observable应用share()函数,而不是从createServiceStatusObservable()方法返回的Observable。有多个观察者被添加到这个观察者以检查当前状态。这意味着执行网络请求的可观察对象被执行了N次(N是观察者的数量)。现在每次点击按钮,网络请求都会执行一次,这就是我需要的。
private func getServiceStatusObservable() -> Observable<String> {
return self.buttonTapped.flatMap { _ -> Observable<String> in
return self.createServiceStatusObservable()
}.share()
}
答案 0 :(得分:5)
.shareReplay(1)
仅适用于observable的一个实例。在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
}
}
}
使用此版本时,serviceStatusObservable
只会创建一次,因此每次使用时都会分享副作用,因为它是相同的实例。