Simple Event-Emitter/PubSub pattern

Published on
2 mins read
5 views

Simple Event Emitter or PubSub pattern

class Event {
  constructor() {
    this.events = {};
  }

  subscribe(event, handler) {
    this.events[event] = this.events[event] || [];
    this.events[event].push(handler);
    return () => this.unSubscribe(event, handler);
  }

  unSubscribe(event, handler) {
    let handlers = this.events[event];
    if (handlers && Array.isArray(handlers)) {
      for (let i = 0; i < handlers.length; i++) {
        if (handlers[i] === handler) {
          handlers.splice(i, 1);
          break;
        }
      }
    }
  }

  emit(event, ...args) {
    (this.events[event] || []).forEach((handler) => {
      handler(...args);
    });
  }
}

Usage

// Create a global instance in your app
let globalEvent = new Event();

let handler1 = (data) =>
  console.log(`handler1(): FOO event emiited with data: ${data}`);
let handler2 = (data) =>
  console.log(`handler2(): FOO event emiited with data: ${data}`);

// Subscribe to event
globalEvent.subscribe("FOO", handler1);
globalEvent.subscribe("FOO", handler2);

// Emit event when needed
globalEvent.emit("FOO", "foo");

// Expected:
// handler1(): FOO event emiited with data: foo
// handler2(): FOO event emiited with data: foo

// Unsubscribe event
globalEvent.unSubscribe("FOO", handler2);

// Then
globalEvent.emit("FOO", "bar");

// Expected:
// handler1(): FOO event emiited with data: bar