DEV Community

Cover image for Understanding the PubSub (Publish-Subscribe) Design Pattern in JavaScript
Ashok
Ashok

Posted on

Understanding the PubSub (Publish-Subscribe) Design Pattern in JavaScript

The Publish-Subscribe (PubSub) pattern is a popular design pattern used to facilitate communication between different parts of an application without them needing to know about each other directly. This pattern is especially useful for decoupling components in large-scale applications, where events can be published and subscribers can react to these events.

In this article, we'll explore how to implement the PubSub pattern in JavaScript using both an object-based approach and a class-based approach. By the end, you'll have a solid understanding of how to use this pattern in your own projects.

Object-Based Implementation
The object-based approach is simple and effective for scenarios where a single global event manager is sufficient. Here's how you can implement it:

pubsub.js
const PubSub = {
    subscribers: [],

    subscribe: function(subscriber) {
        this.subscribers.push(subscriber);
    },

    publish: function(payload) {
        this.subscribers.forEach(subscriber => {
            subscriber(payload);
        });
    }
};

export default PubSub;
Enter fullscreen mode Exit fullscreen mode

How to Use the Object-Based PubSub
In your application, you can import the PubSub object wherever you need it. Here’s an example:

// file1.js
import PubSub from './pubsub';

PubSub.subscribe((payload) => {
    console.log('File 1 received:', payload);
});
Enter fullscreen mode Exit fullscreen mode
// file2.js
import PubSub from './pubsub';

PubSub.subscribe((payload) => {
    console.log('File 2 received:', payload);
});
Enter fullscreen mode Exit fullscreen mode
// main.js
import PubSub from './pubsub';

PubSub.publish('Hello from main!');
Enter fullscreen mode Exit fullscreen mode

Class-Based Implementation
For more flexibility or when you need multiple instances of a PubSub system, a class-based approach can be used. This allows you to create independent PubSub instances with their own list of subscribers.

class PubSub {
    constructor() {
        this.subscribers = [];
    }

    subscribe(subscriber) {
        this.subscribers.push(subscriber);
    }

    unsubscribe(subscriber) {
        this.subscribers = this.subscribers.filter(sub => sub !== subscriber);
    }

    publish(payload) {
        this.subscribers.forEach(subscriber => {
            try {
                subscriber(payload);
            } catch (error) {
                console.error('Error in subscriber:', error);
            }
        });
    }
}

export default PubSub;

Enter fullscreen mode Exit fullscreen mode

How to Use the Class-Based PubSub
Here's an example of how you can use the class-based PubSub pattern in your application:

import PubSub from './pubsub';

// Create an instance of PubSub
const pubSubInstance = new PubSub();

// Subscribe to events
pubSubInstance.subscribe((payload) => {
    console.log('Instance 1 received:', payload);
});

pubSubInstance.subscribe((payload) => {
    console.log('Instance 2 received:', payload);
});

// Publish an event
pubSubInstance.publish('Hello from instance!');

Enter fullscreen mode Exit fullscreen mode

Conclusion
The PubSub pattern is a powerful tool for managing communication between different parts of your application. Whether you choose to use an object-based or class-based implementation depends on your specific needs. The object-based approach is simple and straightforward, ideal for smaller projects or when a single global event manager is sufficient. On the other hand, the class-based approach offers more flexibility and is better suited for larger applications where you may need multiple instances of the PubSub system.

Feel free to use these examples in your own projects and modify them to suit your needs. Happy coding!

Top comments (0)