Reactive programming is one of the hottest topics today. With libraries like RxJs and big frameworks such as Angular adopting it, it constantly continues to grow.

In my experience, it’s hard to explain Observables to someone who doesn’t have much experience with functional programming. In most cases it requires a bit of a mind shift.

Observables come with a lot of operators and concepts. People are often overstrained by reactive programming, because they never fully understand how Observables work.

But here’s the good thing. The main concepts of Observables aren’t as complicated as they might seem on a first glance. In fact they have a lot in common with pure JavaScript functions. What? Find out more on my blog post on:

As the title says, this blogpost tries to demystify Observables. In my opinion there’s just one way to do so; by writing our own custom Observable.😎

Writing our own Observable sounds complicated but it’s not rocket science. In fact, you’ll be surprised how easy it is to implement your own basic Observable.

MyObservable, cold and lazy

Most, but not all Observables are lazy! Maybe you have already heard the terms cold and hot Observables.

For simplicity let’s focus on the major part of Observables which are cold — lazy. They don’t do anything until you tell them to do so. But how do you tell them to do something?

Let’s first have a look at the Observables constructor function. We’re going to use this function to create an Observable that emits 1,2,3 and then completes.

const example$ = new Rx.Observable(function(observer){

observer.next(1)

observer.next(2)

observer.next(3)

observer.complete()

}) example$.subscribe(next => console.log(next),

err=> console.error(err),

() => console.log('Done')) // Output

// 1

// 2

// 3

// Done

We call the constructor function and pass in a callback. Guess what this callback is called. Right, subscribe!

Follow me on Twitter or medium to get notified about the newest blog posts and interesting frontend stuff!🐤

In fact it’s the same subscribe we are going to call five lines later. To get a clearer understanding let’s refactor the above snippet in the following way:

const subscribe = function(observer){

observer.next(1)

observer.next(2)

observer.next(3)

observer.complete()

} const observer = {

next: next => console.log(next),

error: err => console.error(err),

complete: () => console.log('Done')

} const example$ = new Rx.Observable(subscribe)

example$.subscribe(observer)

It’s important to understand that the subscribe function we are passing in at the beginning is the same that we are going to call later when we subscribe to our stream. But how does this work?

If you have read my other blogpost about “Observables, just powerful functions” you may already have an idea.

Let’s go on and implement a very basic observable. Again, you will be shocked how little code it is.

class MyObservable {



constructor(subscribe) {

this._subscribe = subscribe

}



subscribe(observer) {

return this._subscribe(observer);

}

}

The constructor of MyObservable accepts a subscribe callback and assigns it to an internal _subscribe field.

By calling the public subscribe we then internally call _subscribe with the passed in Observer. With this function call we kick off our observable and tell him to call next on our observer with 1, 2, 3 and then complete.

Great!! We can now easily take our snippet from the top and swop the Rx.Observable with our own custom MyObservable.

But wait. Remember how we passed three functions instead of an Observer object? In our current implementation this isn’t possible yet.

Accept callbacks and observer objects 🤝

To accept callbacks and observers we‘re going to implement some small converting logic.

If the user passes in three functions instead of a callback, we’ll convert those callbacks to an Observer object that we’ll then pass to our internal subscribe function.

subscribe(next, error, complete) {

let observer;

if (typeof next === 'function') {

observer = {

next,

error: error || function () {},

complete: complete || function () {}

}

} else {

observer = next;

}

return this._subscribe(observer);

}

Converting the callbacks to an Observable object is quite simple.

If the first passed in value is a function we‘ll create our own observer internally. In case the user doesn’t pass in an error or complete function we’ll just assign an empty function to our Observable. If the consumer decides to pass in an Observer object we won’t convert anything and directly use the Observer object.

Awesome! We’ve created a very basic implementation of an Observable. 🤠

Observables require a mind shift but they’re not pure magic.

🧞‍ 🙏 By the way, click the 👏🏻 clap 👏🏻button on the left side (up to 50x) if you enjoyed this post.

Claps help other people finding it and encourage me to write more posts

Want to know how to test your Observable chains? Then check out my article on “Findings about RxJs marble testing and the TestScheduler”.