Description

Often times you want to let certain actions trigger other ones. This can be done either by using js built in HTMLElement.addEventListener() or building out your own for non html classes.
?

Reach for when

You have JS that needs to be driven by events like a media player.

Pseudocode

on (event, callback) -> push to event array
off (event) -> remove from event array
emit (event, ...args) -> call all events
once (event, callback) -> do emit but remove itself after done

Code

class EventEmitter {
  constructor() {
    this.events = {};
  }
  on(event, cb) {
    (this.events[event] ??= []).push(cb);
    return this;
  }
  off(event, cb) {
    this.events[event] = (this.events[event] || []).filter(f => f !== cb);
    return this;
  }
  emit(event, ...args) {
    (this.events[event] || []).forEach(cb => cb(...args));
    return this;
  }
  once(event, cb) {
    const wrapper = (...args) => {
      cb(...args);
      this.off(event, wrapper);
    };
    this.on(event, wrapper);
    return this;
  }
}