Hone logo
Hone
Problems

Building a Simple Publish-Subscribe System in JavaScript

Publish-Subscribe (pub-sub) is a messaging pattern where publishers send messages to a channel, and subscribers receive messages from that channel without knowing who the publisher is. This decoupling is incredibly useful for building modular and scalable applications, especially in event-driven architectures. Your task is to implement a basic pub-sub system in JavaScript.

Problem Description

You need to create a PubSub class that allows publishers to publish messages to topics and subscribers to subscribe to those topics. The system should support multiple topics and allow subscribers to unsubscribe from topics. The PubSub class should have the following methods:

  • subscribe(topic, callback): Registers a callback function to be executed when a message is published to the specified topic. The topic should be a string. The callback should be a function that accepts a single argument: the message data.
  • publish(topic, data): Publishes a message to the specified topic. All registered callbacks for that topic should be executed, each receiving the data as an argument.
  • unsubscribe(topic, callback): Removes a specific callback function from the list of subscribers for the given topic. If the callback is not found for that topic, the method should do nothing.

Key Requirements:

  • The system must handle multiple topics concurrently.
  • Subscribers should be able to unsubscribe from topics.
  • The order of execution of callbacks for a single topic should be preserved (FIFO - First In, First Out).
  • The subscribe method should return a function that, when called, will unsubscribe the callback. This allows for easier unsubscription.

Expected Behavior:

  • When publish is called, all subscribed callbacks for the topic should be invoked with the provided data.
  • unsubscribe should remove the specified callback from the topic's subscriber list.
  • Calling the function returned by subscribe should remove the callback from the topic's subscriber list.

Edge Cases to Consider:

  • Publishing to a topic with no subscribers.
  • Subscribing to a topic multiple times with the same callback.
  • Unsubscribing with a callback that was not previously subscribed.
  • Publishing to a non-existent topic.

Examples

Example 1:

Input:
const pubSub = new PubSub();
const callback1 = (data) => console.log("Callback 1:", data);
const callback2 = (data) => console.log("Callback 2:", data);

pubSub.subscribe("news", callback1);
pubSub.subscribe("news", callback2);
pubSub.publish("news", "Breaking news!");

Output:
Callback 1: Breaking news!
Callback 2: Breaking news!
Explanation: Two callbacks are subscribed to the "news" topic. Publishing to "news" invokes both callbacks with the message "Breaking news!".

Example 2:

Input:
const pubSub = new PubSub();
const callback1 = (data) => console.log("Callback 1:", data);
const callback2 = (data) => console.log("Callback 2:", data);

pubSub.subscribe("news", callback1);
const unsubscribe = pubSub.subscribe("news", callback2);
pubSub.publish("news", "Important update");
unsubscribe();
pubSub.publish("news", "Another update");

Output:
Callback 1: Important update
Callback 2: Important update
Callback 1: Another update
Explanation: callback1 is always subscribed. callback2 is subscribed and then immediately unsubscribed.  Only callback1 receives the second message.

Example 3: (Edge Case)

Input:
const pubSub = new PubSub();
const callback1 = (data) => console.log("Callback 1:", data);
pubSub.publish("sports", "Game over!");

Output:
(No output)
Explanation: No subscribers are registered for the "sports" topic. Publishing to "sports" has no effect.

Constraints

  • The topic parameter in subscribe, publish, and unsubscribe must be a string.
  • The callback parameter in subscribe and unsubscribe must be a function.
  • The data parameter in publish can be of any data type.
  • The implementation should be reasonably efficient for a small number of topics and subscribers (e.g., up to 100 topics and 10 subscribers per topic). Extreme performance optimization is not required.
  • The code should be well-structured and readable.

Notes

  • Consider using a JavaScript object or Map to store topics and their associated callbacks.
  • Think about how to handle the return value of subscribe to allow for easy unsubscription.
  • Focus on the core functionality of the pub-sub system. Error handling and more advanced features (e.g., filtering, priority queues) are not required for this challenge.
  • The order of callbacks for a given topic is important. Ensure that callbacks are executed in the order they were subscribed.
Loading editor...
javascript