javascript

Event System - Sigma Computing - 12/22/21

/*

We'd like to build an event system. It should have the following methods:

* on(eventName, listener) adds the listener for eventName and does not resolve the duplicates;
* off(eventName, listener) removes the listener for eventName if such combination exists;
* emit(eventName) invokes all event listeners of eventName.
* clear()

once(eventName, listener)
*/

let events = {}; // [{ listener: (){}, isOnce: boolean }]

// register the listener twice; don't need to detect if already exists
function on(eventName, listener) {
  const event = {
    listener,
    isOnce: false 
  }
  
  if (events[eventName]) {
    events[eventName].push(event); 
  } else {
    events[eventName] = [event]; 
  }
}

function off(eventName, listener) {
  if (events[eventName]) {
    events[eventName] = events[eventName].filter((registeredListenerObj) => {
      const registeredListener = registeredListenerObj.listener
      
      return registeredListener !== listener
    })
  }
  // TODO: Do we want to delete the key if there are no more listeners
}

function emit(eventName) {
  if (events[eventName]) {
    events[eventName].forEach((registeredListener) => { 
      const listener = registeredListener.listener
      const isOnce = registeredListener.isOnce
      
      listener();
      
      console.log("listener", listener)
      console.log("isOnce", isOnce)
      if (isOnce) {
        off(eventName, listener);
      }
    });
  }
}

function clear() {
  events = {};
}


function once(eventName, listener) {
  const event = {
    listener,
    isOnce: true
  };
  
  if (events[eventName]) {
    events[eventName].push(event); 
  } else {
    events[eventName] = [event]; 
  }
}



const listener = () => {
  console.log("eventName listener");
}

const secondListener = () => {
  console.log("second eventName listener");
}

// on("eventName", listener)
// on("eventName", listener)
// console.log(events)
// on("eventName", secondListener)
// console.log(events)
// on("second eventName", listener)
// console.log(events)

// emit("eventName")
// emit("second eventName")
// emit("does not exist")

// off("eventName", listener)
// console.log("off", events)
// off("eventName", listener)
// console.log("off", events)
// off("second eventName", listener)
// console.log("off", events)
// off("does not exist", listener)
// console.log("off", events)


// emit("eventName")
// emit("second eventName")

// clear()
// console.log("clear", events)
// emit()

// on("eventName", listener)
// console.log(events)

once("eventName", listener);
console.log(events)
emit("eventName")
console.log(events)
Was this helpful?