I’m a bit confused by the seemingly conflicting definitions of Hot and Cold observables between the way the book defines it* (Chapter 15, page 286) → “Hot observables have no side effects upon subscription, Cold observables do” and the way it seems to be defined many other places → “Hot observables emit values even if there are no observers, and some observers may miss some values. Cold observables begin emitting every value on every subscription, so that every observer gets to see every value.”
I’m having a hard time reconciling these two competing definitions. For example, I can think of a very simple “Cold Observable” that performs no side effects upon subscription: Observable.from([1, 2, 3]). Based on the book definition, that’s a hot observable because there are no side effects. But using the other definition it is clearly a cold observable since every observer will get 1, 2 and 3.
Alternatively, I can think of someone perhaps making an otherwise hot observable, that makes an api call to a server every 15 minutes, and subscribers will the results of those api calls. This would be a cold observable according to the book definition, but a hot observable according to the other definitions, since these api calls will be happening every 15 minutes even if there are no observers.
Can anyone help clarify this issue? Perhaps point out some way to think of it more constructively?
The side effect of subscribing this observable is that the values 1, 2, and 3 are emitted. This side effect will be performed each time you subscribe the observable.
I really don’t think that the emission of elements counts as side effects. According to the book, side effects are things like:
API Calls
Editing database
Writing to file system
Launching a rocket
These are things that can make changes to the environment or cause significant work to be done. This is not the case for emission of elements, especially fixed immutable elements like in the Observable example above.
Thanks for your response! Not here to argue either, just trying to understand.
That’s an interesting way to look at it. So a hot observable doesn’t emit elements on subscription because elements are emitted due to other [presumably external, ‘side-effecty’] factors, whereas a cold observable emits all elements immediately. Still trying to square that with the definition of side effects.
In your example, what if your “portrait” and “landscape” hot observable includes something like .replay(3)? Then each subscriber will get the last three values, even though nothing has happened to the phone to cause those values to be emitted. Is this still a hot observable without side effects?
edit: I think I’m starting to understand this a bit more. It helps me to view it as if some side effect needs to take place for every element to be emitted (i.e. a network call to some server, or database lookup). In this case, the side effects will be triggered for every element in a cold observable, with every subscription. In a hot observable, these side effects happen independently of observer subscriptions. What was tripping me up was that every element doesn’t always need side effects to be produced, as in our simple Observable.from([1, 2, 3]) above. But for the purposes of classifying the Observable as hot or cold, you simple assume that there are (or that there could be).
Emitting elements doesn’t have to do with whether an observable would be classified as hot or cold (I personally think the difference is meaningless in Rx where you have only cold ones anyway). The argument of hot vs. cold is mostly raised by people coming from other frameworks where the difference has some meaning.
“Performing side effects upon subscription” really means “does it do ANYTHING upon subscribing”.
Open the book on pages 56-58 where Observable.create {...} is being introduced. The code in the closure is what is being executed when an observer subscribes to the observable. In RxSwift whenever you subscribe an observable this closure is being executed and it’s its responsibility to emit some values - the code inside can have any logic. In the case of convenience shortcuts like Observable.from([1,2,3]) - that creates an observables whose create closure (so to say) loops over the array and emits immediately each of the elements. So, this is performing “side effects” (or as said “doing anything”) - emitting values from within the closure that is being executed upon subscribing is performing side effects.
That’s why the observables in RxSwift are being referred to as “cold” - they aren’t “working” unless somebody has subscribed them and therefore executed the code in their create closure that would perform some work and emit values.
A hot observable (which as said it’s not used in RxSwift except for testing) would be working as soon as it’s created regardless whether somebody has subscribed it or not. Therefore when it’s subscribed it doesn’t need to perform any side effects to start producing values (elements). That’s why it’s being called “hot”, because it’s already “going” when you subscribe for it (even the first time).
I hope this clarifies the situation a bit more. In any case - I wouldn’t waste much time with that since (as mentioned) there’s no way to create a hot observable in RxSwift except in tests.
Yea. This is all starting to make much more sense, and I think I have a much better handle on hot/cold and side effects. Thanks for that helpful description.
I was following it all pretty well up until you said that all observables in RxSwift are cold (except for testing). Isn’t it a hot observable anytime you use Subjects, like PublishSubject or BehaviorSubject?