Jake Pruitt

This is where I write.

← Home


Both server-side and browser-side JavaScript have the idea of events, and many JavaScript applications operate on the basis of performing actions when certain events occur. In browser-land, the most important events are triggered when the user interacts with the page, like clicking a button or entering a form. JavaScript listens for these events and calls the appropriate “callback” or “event handler”. For instance, to register a function to be called whenever someone clicks on a paragraph element, you could write:

var paragraph = document.querySelector('p');
paragraph.addEventListener('click', function(evt) {
  paragraph.style.color = 'blue';

It is also possible to create custom events and register handlers to those, for instance:

var ev = new Event('myCustomEvent');
document.addEventListener('myCustomEvent', function() {
  console.log('Hello custom event!');


The server side

For server-side JavaScript, many objects implement the EventEmitter class. EventEmitters have basic publish/subscribe methods, including on to register events and emit to fire events. Many things implement the EventEmitter class, including HTTP servers and streams. For instance, if you want to listen for a server to have a connection, you can write:

server.on('connection', function (stream) {
  console.log('someone connected!');

When the event 'connection' fires, the anonymous function will be called. In design pattern lingo, this is typically known as the publish/subscribe pattern, or pub/sub. The publisher is the thing that emits events, in this case, the server. The subscriber is the callback function that logs 'someone connected!' when the event is fired. It’s pretty great that both server and browser come with pub/sub somewhat baked in.

Here are the advantages of using publish/subscribe:

  1. The listeners and emitters do not need to know anything about each other in order to work together. This allows you to decouple your code more easily, following the law of Demeter.
  2. Registering events is a very quick process, which means an application can be initialized without blocking the event loop. Performance difficulties arise when there are multiple listeners assigned to each event, and Node warns against the use of more than ten listeners on any single event in an EventEmitter.

Seneca is a microservice tool that primarily acts as an EventEmitter, with a lot of built-in functionality to make creating an application simpler to reason about. For instance, rather than using just strings to register and call events, JSON strings can be used with pattern matching to get the closest possible match. If you plan on using Seneca in a project, it is important that you begin thinking in terms of events and listeners.