RxJS, understanding defer
Quite simply, because Observables
can encapsulate many different types of sources and those sources don't necessarily have to obey that interface. Some like Promises
always attempt to eagerly compete.
Consider:
var promise = $.get('https://www.google.com');
The promise in this case is already executing before any handlers have been connected. If we want this to act more like an Observable
then we need some way of deferring the creation of the promise until there is a subscription.
Hence we use defer
to create a block that only gets executed when the resulting Observable
is subscribed to.
Observable.defer(() => $.get('https://www.google.com'));
The above will not create the Promise
until the Observable
gets subscribed to and will thus behaves much more in line with the standard Observable
interface.
Take for example (From this article):
const source = Observable.defer(() => Observable.of(
Math.floor(Math.random() * 100)
));
Why don't just set the source
Observable to of(Math.floor(Math.random() * 100)
?
Because if we do that the expression Math.floor(Math.random() * 100)
will run right away and be available in source
as a value before we subscribe to source
.
We want to delay the evaluation of the expression so we wrap of
in defer
. Now the expression Math.floor(Math.random() * 100)
will be evaluated when source
is subscribed to and not any time earlier.
We are wrapping of(...)
in the defer
factory function such that the construction of of(...)
happens when the source
observable is subscribed to.