Home

Node And Event Emitters

This is not to be confused with the ideas involved in Event Driven Architecture.
Node provides the EventEmitter that can be used to write programs that operate with events.

const { EventEmitter } = require("events");

// one way of making an event object
const dataHandler = new EventEmitter();

// another, maybe more 'traditional' way to do the same
class dataHandler extends EventEmitter {
  constructor(opts = {}) {
    super(opts);
    this.name = opts.name;
  }
}

Emitting And Listening For Events

// a var event name
const CONNECT_TO_DB = 'connectToDb';
const START_API = 'startApi';

// register some event handlers:
// two for CONNECT_TO_DB
// one for START_API
dataHandler.on(CONNECT_TO_DB, handleParamsFn);
dataHandler.on(CONNECT_TO_DB, logSomething);
dataHandler.on(START_API, startTheApi);

// call the event and pass some data
dataHandler.emit(CONNECT_TO_DB, dbParams);

On Events

Events come from EventEmitter instances, a node built-in detail.
Event names are strings.
Events get event-handlers registered to them.
Events get emitted. Emitted events can take parameters that get passed to the handler.

Some Interesting bits

  • the ORDER of emitting && listening matters...
    • if event.emit is written before the event.on listener registration, the listener will not catch the emit!
  • multiple fns can happen on a single event even, above the handleParamsFn and logSomething both happen on connection to a db

prependListener

prependListener is a method on the eventEmitter instance.
This registers listeners at the beginning of a (potential) listeners array (if there are many listeners, each listener is an item in an array).

dataHandler.prependListener("event-name", prependFn);

once

function singleHandle(){
  console.log('single handler was called!')
}
dataHandler.once("single-event-instance-handler", singleHandler);
dataHandler.emit("single-event-instance-handler");
dataHandler.emit("single-event-instance-handler");

// this will only log "single handler was called!" once - not 3x

the event removes itself after it is called once. emitting the event again, with this once handler registered, will do nothing && throw no error.

Removing Event Listeners

removeListener

  • used to remove a listener that has been registered
  • can take 2 args/params
    • event name
    • event listener fn
dataHandler.removeListener("event-name", handleParamsFnTwo);

removeAllListeners

dataHandler.removeAllListeners("event-name");

Error Events

When an event gets emitted with an error, the error event gets triggered/emitted.
This is critical to handle and NOT crash the node process: without an error event handler written (.on("error", errorHandler)), the whole node process crashes. With the error event handler written, and an EventEmitter encounters an error, the node process will continue!

const { EventEmitter } = require("events");
const thisTry = new EventEmitter();

// keep process alive
process.stdin.resume();

thisTry.on("error", (err) => {
  console.log("got error:", err.message);
});

thisTry.emit("error", new Error("dummy err message"));

Event Driven Architecture

Again, this is a different topic.
Using the above EventEmitter in a node process is one thing.
Setting up a system's architecture to be driven by events is a whole other consideration.
Surely a node process that leverages the EventEmitter can be part of an event-driven system.

Some References

Links about event-driven-architecture

Tags: