Demystifying Rxjs Observable

Ankur
Ankur
Sep 3, 2017 · 5 min read

Lets try to find out what really is an Observable and try to write its simple implementation . I will try to explain in a way after which you will feel confident in using rxjs observables. There are many buzz words around we listen like its lazy , hot observable , cold observable etc etc. Will try to demystify all in the series of article. In this first article i will try to make you understand what really is Observable.

Lets try to build Observable by mentioning its properties and building the property one by one. This is best way to understand the internals.


  1. Observable is a function (period) :- Its just a function which takes one parameter or three callback (observer) and returns a tear down function. Yes that’s it and its true. Lets create an observable which pushes first three odd numbers starting from 0.
function firstThreeOddNumbers$ (observer) {
observer.next(1);
observer.next(3);
observer.next(5);
observer.complete();
return () => console.log('clean up function');}

Here we go , you just wrote your first observable to which if you subscribe you get first three odd numbers.

Let me reiterate and stamp this on your mind , Observable is just a function.


2. Observable is lazy :- We often hear this a lot but never really try to think what really it means. Actually its really simple , functions in javascript or most other languages are lazy. It just means if we define the function its not doing anything until we call the function. I think this every knows and now as we know observable is also a function. Hence its lazy in nature is due to the fact that its just a function and it will not do anything until it is being called. Surprised ? Yes , its just a buzz word and now you know why observable is lazy. Lets come to our example we defined our observable as a function `firstThreeOddNumbers(observer){}` which is not doing anything until we call it. Lets call our observable.

// call the functionconsole.log('start');const unSub = firstThreeOddNumbers$({
next: (x) => console.log(x),
error: (error) => console.log(error),
complete: ()=> console.log('complete')
});

unSub();
console.log('end');
//output
start
1
3
5
complete
clean up function
end

so as soon as we call the function we start getting the data out from the observable (1, 3, 5) or simply say function is being executed and it also returned the clean up function which we call so that no memory leak happens.

I know you might be thinking , is it really that simple ? yes trust me it is. Its just a function(lazy in nature by default) and inside the function we just connect with some data producer to the observer passed in as the parameter.

So to wrap up Observable is a function , we call the function , function is being executed which starts pushing the data from data producer to observer by calling observer.next().


3. Observable is sync or async based on the what we do inside the function

You might we wondering observable is suppose to be asynchronous, what are you saying ? Let me reiterate again Observable is just a function and function by default is synchronous and lazy in nature. If you see the output of our above code snippet also it is simple synchronous with below output.

start
1
3
5
complete
clean up function
end

start is printed first and data producer start pushing the data , then complete is called , unSub is called and then end is printed. Its absolutely synchronous. And obviously as its a function it is suppose to be synchronous.

If we want it to be async then we need to do async operation or add some scheduler inside the function which will make it async.

Lets make our observable async

function firstThreeOddNumbers$ (observer) {
const id = setTimeout(() => {
observer.next(1);
observer.next(3);
observer.next(5);
observer.complete();
return () => {
console.log('clean up function');
clearTimeout(id);
}
}, 5000);
}console.log('start');const unSub = firstThreeOddNumbers$({
next: (x) => console.log(x),
error: (error) => console.log(error),
complete: ()=> console.log('complete')
});
console.log('end');setTimeout(() => unsub() , 10000 );//outputstart
end
1
3
5
complete
clean up function

now we see that start and end is printed first and setTimout handler is called in async way (in next tick) which pushes the data out and completed.

Surprised again ? yes thats it. If inside the function we push the data asynchronously then observable is async and otherwise it is synchronous.


4. Observable function is wrapped in a class :- Mostly we are using the Rxjs library in our projects and we see subscribe and Observable types.

Is it something different ? Under the hood it is still the function

Rxjs actually just wrap that observable function in a class.

class Observable {
constructor(fn) {
this.subscribe = fn;
}
}
source$ = new Observable(firstThreeOddNumbers);source$
.subscribe(observer);

Again Surprised ?

subscribe is just the property on the class Observable which points to our main observable function. So if we call the subscribe we are just calling that function. Think again, calling subscribe means we are just calling our main observable function which pumps the data to the observer in sync or async way.

5. Observable is unicast in nature :- We might have heard or experienced that if we wrap the http calls in the Observable and if we subscribe it makes the http call. If we again subscribe to the same Observable it makes again the same call. Its due to the fact that Observable is unicast in nature. Means it is connecting the one instance of producer of data to one observer only.

To make it simple again lest go back to basics. When we call subscribe we are just calling the function. So think again if we call subscribe on same observable again then what might happen. ? it is again calling the same function and executing the same code inside the function. And thats it. Its really as simple as that.

source$ = new Observable(firstThreeOddNumbers);source$.subscribe(observer1);
source$.subscribe(observer2);
output1
3
5
complete
tear down function
1
3
5
complete
tear down function

Even in our example we can see subscribing twice to same observable is calling the function twice.

Basically our Observable is not much different to the Observable for the http calls. In the http case the main observable function might be doing the ajax call and as soon as the result from server is back then observer.next(result) will be called.

So we subscribe to it twice then really we are calling the server twice.

I am sure or atleast hope now as we understand the basics it might be really simple in understanding the above case.


To Wrap up Let me give you a definition of Observable in a summary.

  1. Observable is just a function . Function by nature is lazy and Synchronous and hence is the Observable.
  2. Inside the function we have to just connect the data producer to the data consumer (observer). Data producer pushes the data to data consumer through observer.next().
  3. Data Producer can push the data in a sync or async way.

.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade