JavaScript Interview Questions: Emitter (Pub-Sub)
You have an Object, an important one! You want to perform a certain action when something changes to this Object - but How will you know that something has changed?
the answer is: Observer Pattern
With the Observer pattern, you can observe any change to your Object. This Object could be as simple as a String or a normal Object.
Pub-Sub or an Emitter is a specific case of linking any change on your system to a String.
We call it a Topic
. You subscribe to changes linked to that topic and when any change publish to that topic, everyone gets a notification.
It is just like subscribing to any topic on Medium, whenever an article is published for that Topic, every subscriber receives a notification through emails.
Building Block of Observer Pattern
subscribe()
: A method to add subscribers.unsubscribe()
: A method to remove subscribers.publish()
: A method to notify all observers whenever a change occurs
Observer Pattern = Publish + Subscribe
Building a PubSub Module using Observer Pattern
How does PubSub System work?
Design Principles:
- The module must expose “Public Contract” i.e. Standard
publish()
andsubscribe()
methods. - Internals of modules like
subscribers
array must be hidden from users.
Let’s start by creating a simple Subscribe and Publish
Testing:
This code will give us the following output:
First Subscriber on MY_TOPIC: Simple PubSub
Second Subscriber on MY_TOPIC: Simple PubSub
This is good enough to subscribe and publish, but over time, it will take down our system as we don’t have any way to remove a subscriber, so let’s build that next.
An UnSubscriber!
...
unSubscribe(topic, callback) {
const idx = subscribers[topic].indexOf(callback);
if (idx >= 0) {
// Remove the callback from the topic subscribers
subscribers[topic] = subscribers[topic].filter((subscriber) => subscriber !== callback);
}
},
...
This will make our module almost ready!
The above code will output like below:
First Subscriber on MY_TOPIC: Simple PubSub
Second Subscriber on MY_TOPIC: Simple PubSub----REMOVING SECOND SUBSCRIBER---
First Subscriber on MY_TOPIC: Simple PubSub----REMOVING ALL SUBSCRIBER---
<none>
With this, we are almost ready to ship! with one gotcha!
What’s that??
Our code has one BUG!! check this block of code and think about how it can fail for special keywords like toString
subscribe(topic, callback) {
if (!(topic in subscribers)) { // This will pass
subscribers[topic] = [];
}subscribers[topic].push(callback); // This line will break :(
},
How?
subscribers
is an Object
and like any other Object
in JavaScript, it inherits property from the parent base Object
including toString
.
Solution?
Don’t let anyone to create a Topic with a special name. Fix:
This will throw error like:
Error: provided topic : toString is a reserved keyword.