Last active
July 27, 2017 17:06
-
-
Save inamiy/31bd4c3480f9a4a6c2e945c211c7fed0 to your computer and use it in GitHub Desktop.
Rx "Hot -> Cold" + multiple subscription behavior
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
print("=== signal (hot) ===") | |
do { | |
let (signal, observer) = Signal<Int, NoError>.pipe() | |
let s = signal | |
.map { x -> Int in | |
print("map \(x)") | |
return x | |
} | |
s.observeValues { _ in } | |
s.observeValues { _ in } // subscribe twice | |
observer.send(value: 1) | |
observer.send(value: 2) | |
} | |
print("=== producer(signal) (warm) ===") | |
do { | |
let (signal, observer) = Signal<Int, NoError>.pipe() | |
let s = SignalProducer(signal) | |
.map { x -> Int in | |
print("map \(x)") | |
return x | |
} | |
s.startWithValues { _ in } | |
s.startWithValues { _ in } // subscribe twice | |
observer.send(value: 1) | |
observer.send(value: 2) | |
} | |
//=== signal (hot) === | |
//map 1 | |
//map 2 | |
//=== producer(signal) (warm) === | |
//map 1 | |
//map 1 | |
//map 2 | |
//map 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
print("=== hot -> map (cold) ===") | |
do { | |
let pub = PublishSubject<Int>() | |
let o = pub | |
.map { x -> Int in | |
print("map \(x)") | |
return x | |
} | |
o.subscribe() | |
o.subscribe() | |
pub.onNext(1) | |
pub.onNext(2) | |
} | |
extension ObservableConvertibleType { | |
// Custom `map` using `Observable.create` (which is cold) | |
func map2<E2>(_ f: @escaping (E) -> E2) -> Observable<E2> { | |
return Observable.create { observer in | |
return self.asObservable() | |
.subscribe(onNext: { x in | |
observer.onNext(f(x)) | |
}, onError: { e in | |
observer.onError(e) | |
}, onCompleted: { | |
observer.onCompleted() | |
}) | |
} | |
} | |
} | |
print("=== hot -> map2 (same as map, cold) ===") | |
do { | |
let pub = PublishSubject<Int>() | |
let o = pub | |
.map { x -> Int in | |
print("map \(x)") | |
return x | |
} | |
o.subscribe() | |
o.subscribe() | |
pub.onNext(1) | |
pub.onNext(2) | |
} | |
print("=== hot -> Driver.map (hot) ===") | |
do { | |
let pub = PublishSubject<Int>() | |
let o = pub | |
.asDriver(onErrorDriveWith: .empty()) | |
.map { x -> Int in | |
print("map \(x)") | |
return x | |
} | |
o.drive() | |
o.drive() | |
pub.onNext(1) | |
pub.onNext(2) | |
} | |
//=== hot -> map (cold) === | |
//map 1 | |
//map 1 | |
//map 2 | |
//map 2 | |
//=== hot -> map2 (same as map, cold) === | |
//map 1 | |
//map 1 | |
//map 2 | |
//map 2 | |
//=== hot -> Driver.map (hot) === | |
//map 1 | |
//map 2 |
Hi @sergdort ✋
You are right, and I also think it's wise to use share
only at the bottommost observable pipelining just before subscription (if possible).
But as far as I see Driver
operator impls e.g. Driver.map
, I don't think its concept is limited to such use case only.
I found it a problem since users can easily get trapped by excessive caching (even with the help of .whileConnected
).
I personally think Driver
operators should not be used for memory efficiency, and only use .drive()
for UI data-binding.
(But maybe I'm too nervous about memory usage!)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, @inamiy
Based of my knowledge of Rx :)
I feel like you think about
share..
operators from the wrong perspective. They are designed to sharesubscription
not asequence
.What I I'm trying to say is how
Map
(or any other operator) works, is that internally it subscribes to the source, and this is what you want to share :)So if you do is :
I believe it should work.
From my understanding of how Rx is designed is that
subscription
is "in charge". That's why it's calledObservable
sequence you can "start" observing it by subscribing to it. Andshare..
operators there are just an optimisation operators e.g so you don't do the same work for new subscription.Hope it make sense :) And please correct me if was wrong at some point!