RxSwift:如何使用 shareReplay 懒惰地获取订阅
Posted
技术标签:
【中文标题】RxSwift:如何使用 shareReplay 懒惰地获取订阅【英文标题】:RxSwift: How to use shareReplay to lazily get subscription 【发布时间】:2016-04-11 02:10:29 【问题描述】:所以我希望能够懒惰地订阅共享数据,而不会在没有人订阅的情况下持续存在。然后如果有人再次订阅,就会创建一个新的 observable。我会使用变量,但如果没有人订阅,我不希望它持续存在(因为如果我使用数组或大于 int 的东西,我不想将它们保存在内存中)。我当前的实现工作,除非重新订阅它仍然获得最后一个值,这意味着该值仍然存在。我正在考虑将 observable 设置为 nil,但我不知道在哪里做。谁能帮我完成这个?下面的代码显示它大部分都在工作,但看起来数据在没有人订阅的情况下仍然存在。
var switchTwoDisposable: Disposable? = nil
@IBAction func switchOneChanged(sender: UISwitch)
if sender.on
self.switchOneDisposable = currentNumber().subscribeNext (value) in
log.debug("Switch 1: \(value)")
else
switchOneDisposable?.dispose()
@IBAction func switchTwoChanged(sender: UISwitch)
if sender.on
self.switchTwoDisposable = currentNumber().subscribeNext (value) in
log.debug("Switch 2: \(value)")
else
switchTwoDisposable?.dispose()
var numberObservable: Observable<Int>? = nil
func currentNumber() -> Observable<Int>
if let number = numberObservable
return number
self.numberObservable = Observable<Int>.interval(5.0, scheduler: MainScheduler.instance).shareReplay(1)
return self.numberObservable!
// Switch 1 turned on
// logs "Switch 1: 0"
// logs "Switch 1: 1"
// Switch 2 turned on
// immediately logs "Switch 2: 1"
// logs "Switch 1: 2"
// logs "Switch 2: 2"
// Switch 1 turned off
// logs "Switch 2: 3"
// Switch 2 turned off
// nothing happens here until we take action again
// Switch 1 turned on
// logs "Switch 1: 3"
// logs "Switch 1: 0"
【问题讨论】:
【参考方案1】:我终于找到了可以满足我需要的便捷方法。 observable 上的shareReplayLatestWhileConnected()
会将最新的值重播给第 2、3、4 等订阅者,但是当所有人都取消订阅时,则不会保留最后的值。
从上面的例子中替换这一行:
self.numberObservable = Observable<Int>.interval(5.0, scheduler: MainScheduler.instance).shareReplay(1)
...用这一行:
self.numberObservable = Observable<Int>.interval(5.0, scheduler: MainScheduler.instance).shareReplayLatestWhileConnected()
更新
在我的例子中,我特别想从磁盘中获取一个值(例如核心数据或 NSUserDefaults),然后如果有人更新了该值,他们可以发布一个通知,我将使用rx_notification
观察该通知。因此,为了让这种延迟加载真正起作用,我还需要一个初始值。因此,在这种情况下使用 startWith
会很有帮助,其中 startWith 的值是磁盘上的当前值。所以代码类似于:
Observable<Int>.interval(5.0, scheduler: MainScheduler.instance).startWith(100).shareReplayLatestWhileConnected()
【讨论】:
以上是关于RxSwift:如何使用 shareReplay 懒惰地获取订阅的主要内容,如果未能解决你的问题,请参考以下文章
在 Angular 中使用 shareReplay(1) - 仍然调用 http 请求?
node_modules/rxjs-compat/operator/shareReplay.d.ts(2,10) 中的错误:
[RxJS] Reactive Programming - Sharing network requests with shareReplay()
node_modules/rxjs-compat/operator/shareReplay.d.ts(2,10) 中的错误:错误 TS2305: