Skip to content

Instantly share code, notes, and snippets.

@pgherveou
Last active October 6, 2016 17:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pgherveou/afe692e010e3f3fa8bc7bd07f6919b41 to your computer and use it in GitHub Desktop.
Save pgherveou/afe692e010e3f3fa8bc7bd07f6919b41 to your computer and use it in GitHub Desktop.
reuse shared Observable
import Foundation
import PlaygroundSupport
import RxSwift
PlaygroundPage.current.needsIndefiniteExecution = true
/// dictionary of (id: shared Observable)
var store: [String: Any] = [:]
/// makeSequence return an existing shared sequence identified by `id`
/// or create and store a new one
/// for the purpose of this playground we just create dummy interval sequences
/// but in real code this could be observable emitting data from a websocket, a firebase node...
func makeSequence(id: String, period: RxTimeInterval) -> Observable<Int> {
if let seq = store[id] as? Observable<Int> {
print("store:reuse \(id)")
return seq
}
print("store:create \(id)")
let seq = Observable<Int>
.interval(period, scheduler: MainScheduler.instance)
.do(onDispose: {
print("store:remove \(id)")
store.removeValue(forKey: id)
})
let shared = seq.shareReplay(1)
store[id] = shared
return shared
}
/// test
/// this simulate a sequence observing a model
/// where we need to flatMap to get a nested model attached
let _ = makeSequence(id: "model", period: 1.0)
.flatMapLatest { (index: Int) -> Observable<(game: Int, creator: Int)> in
// received some model updates...
let seq = makeSequence(id: "nested-model", period: 0.2)
// create a subscription that we will dispose
// when the returned sequence dispose, but in an async fashion.
// This way, we get a chance to reuse the same shared sequence
// on the next run of this flatMapLatest block
let subscription = seq.subscribe()
return seq
.do(
onDispose: { DispatchQueue.main.async { subscription.dispose() } }
)
// return the updated model + nested-model data
.map { (index, $0) }
}
.take(8)
.subscribe(
onNext: {
print("emit (model: v\($0.0), nested-model: v\($0.1))")
}
)
// output:
//
// store:create model
// store:create nested-model
// emit (model: v0, nested-model: v0)
// emit (model: v0, nested-model: v1)
// emit (model: v0, nested-model: v2)
// emit (model: v0, nested-model: v3)
// store:reuse nested-model
// emit (model: v1, nested-model: v3)
// emit (model: v1, nested-model: v4)
// emit (model: v1, nested-model: v5)
// emit (model: v1, nested-model: v6)
// store:remove model
// store:remove nested-model
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment