我有一个可观察到的感冒,可能会被多次调用。这个可观察到的任务很昂贵(网络请求),然后完成。我希望这种可观察性只能进行一次网络调用,如果以后需要再次调用它,我希望获得最后发出的值。
如果一个可观察对象没有完成(即,仅发送一个没有完成事件的下一个值),我可以使用。share(replay:1,scope:.whileConnected)函数始终获取最后一个值。不幸的是,这不适用于在请求结束时完成的可观察对象。贝娄是一个例子:
let disposeBag = DisposeBag()
let refreshSubject = PublishSubject<Void>()
override func viewDidLoad() {
super.viewDidLoad()
let observable = Observable<String>.create { observer in
let seconds = 2.0
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
observer.onNext("Hello, World")
observer.onCompleted() // <-- Works when commented out
}
return Disposables.create()
}
.share(replay: 1, scope: .whileConnected)
refreshSubject
.flatMap { _ in observable }
.subscribe(onNext: { response in
print("response: ", response)
})
.disposed(by: disposeBag)
}
@IBAction func refreshButtonHandler(_ sender: Any) {
refreshSubject.onNext(())
}
每次触发refreshSubject时,要打印Hello,World需要2秒钟。但是,如果删除observer.onCompleted()行,则第一次只用2秒,然后返回缓存的响应。
显然,这只是一个例子,在现实世界中,如果可观察对象是否完成,我将没有任何控制权,但无论如何,我总是想重播最后一个值。
let yourColdObservable = Observable<String>.create { observer in
let seconds = 2.0
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
observer.onNext("Hello, World")
observer.onCompleted()
}
return Disposables.create()
}
refreshButton.rx.tap
.startWith(())
.flatMapLatest { _ in yourColdObservable }
.share(replay: 1)
在开始发射物品之前先发射指定的物品序列从可观察的来源启动序列时,在refreshButton上如此假的点击
FlatMap运算符通过应用函数来转换Observable您指定给源Observable发出的每个项目的位置,其中该函数返回一个Observable,它本身发出项目。平面图然后合并这些产生的可观测值的发射,这些合并的结果按其自己的顺序排列。FlatMapLatest是FlatMap的特殊类型,因为当
refreshButton.rx.tap
发出onNext事件时,它将取消先前的Observable。