DEV Community

Bukunmi Odugbesan
Bukunmi Odugbesan

Posted on

Coding Challenge Practice - Question 88

The task is to implement an Event emitter.

The boilerplate code

class EventEmitter {
  subscribe(eventName, callback) {

  }

  emit(eventName, ...args) {

  }
}
Enter fullscreen mode Exit fullscreen mode

Each event name maps to an array of listener functions.

this.events = {}
Enter fullscreen mode Exit fullscreen mode

The event emitter is expected to return a subscription object with a release method. If the event doesn't exist, an array is created

subscribe(eventName, callback) {
  if (!this.events[eventName]) {
    this.events[eventName] = [];
  }
Enter fullscreen mode Exit fullscreen mode

The callback is appended to the array

this.events[eventName].push(callback);
Enter fullscreen mode Exit fullscreen mode

Even if the same callback is added twice, it is stored twice.

The release method should release only the specified subscription

return {
      release: () => {
      if(released) return;
      released = true;

      const listeners = this.events[eventName];
      if(!listeners) return;

      const index = listeners.indexOf(callback);
        if (index !== -1) {
          listeners.splice(index, 1);
        }
      }
    }
Enter fullscreen mode Exit fullscreen mode

A listener is removed while events are being emitted

emit(eventName, ...args) {
    const listeners = this.events[eventName]
    if(!listeners) return;

    listeners.forEach(callback => {
      callback(...args)
    })
  }
Enter fullscreen mode Exit fullscreen mode

The final code

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

  subscribe(eventName, callback) {
    if(!this.events[eventName]) {
      this.events[eventName] = [];
    }
    this.events[eventName].push(callback);

    let released = false;

    return {
      release: () => {
      if(released) return;
      released = true;

      const listeners = this.events[eventName];
      if(!listeners) return;

      const index = listeners.indexOf(callback);
        if (index !== -1) {
          listeners.splice(index, 1);
        }
      }
    }
  }

  emit(eventName, ...args) {
    const listeners = this.events[eventName]
    if(!listeners) return;

    listeners.forEach(callback => {
      callback(...args)
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

That's all folks!

Top comments (0)