What the heck is an event emitter?

Stephen Boyd
The Startup
Published in
4 min readJun 6, 2019
Photo by Tobias Cornille on Unsplash

Events are a crucial part of many different programming languages. I will be focusing on JavaScript, specifically NodeJS, events here though. Node’s architecture is mostly asynchronous event-driven.

What is an Event?

Before event emitters became a thing, if we wanted to use some functionality in our code (such as sending an email when a process has been completed) we would have to call or invoke, the function directly to send the email.

This presented problems, such as in a web server if we wanted to store data then send an email to the user we would have to rely on the email sending functionality to be successful in order to return a proper HTTP response to the client.

The way I like to describe an event is sort of like a broadcast. It can be very similar to your local radio station. Your car radio is tuned to a certain frequency in order to listen in on that station. This means the receiver of your car is filtering all the other frequencies out in order to listen to your favorite rock station. The rock station is sending out a broadcast with the music they are playing. They could be sending whatever they want, and the receiver in your car is playing that on your speakers.

An event emitter works the same way. We have our listener methods (the receiver in your car), and we have our event emitter (the radio station broadcasting).

Listener methods

Your listener methods are listening for a certain event (just like your car radio on a certain frequency). Once this event has been emitted, the method reacts to this event, thus invoking the method. If there is never an event emitted that matches the criteria of the listener, then nothing happens, and just like in your car you get no music.

Event Emitter

Your event emitter sends out a certain event to any method that is waiting to react to it. Just like in a radio stations broadcast, nobody has to be listening in order to actually broadcast the event, but if there are no listeners then nothing happens.

How can we use this?

Just like in the previous email example, event emitters can be used in many different ways.

NodeJS has a built-in events module called…. you guessed it… events. You can use this module to create your own events and play around with it. This is usually the best way to learn.

Example Time

Working Event Emitter

const events = require(‘events’);const emitter = new events.EventEmitter();emitter.on(‘fire’, () => {  console.log(‘Fire!’)});console.log(‘Ready!’);console.log(‘Aim!’);emitter.emit(‘fire’);

This block of code:
1. Imports the events module
2. Creates a new emitter object
3. Creates the listener for the ‘fire’ event
4. Logs Ready! Aim!
5. Emits the ‘fire’ event
6. The listener we created logs Fire!

This is the expected and correct output:

Ready!
Aim!
Fire!

Non-working Event Emitter

One thing you must ensure is that the listener is created before the event is emitted. If it is not, then at the time the event is emitted, there is nothing listening for it. So if we have the code below:

const events = require(‘events’);const emitter = new events.EventEmitter();console.log(‘Ready!’);console.log(‘Aim!’);emitter.emit(‘fire’);emitter.on(‘fire’, () => {  console.log(‘Fire!’)});

This block of code:
1. Imports the events module
2. Creates a new emitter object
3. Logs Ready! Aim!
4. Emits the ‘fire’ event.
5. Creates the listener for the ‘fire’ event

Then we get the output of:

Ready!
Aim!

Passing Arguments to the event listener

Another awesome feature, that is vital to event emitters, is the ability to pass data to the listeners. Just like a station sends it’s music to our radios.

To do this, it is very simple:

const events = require('events');const emitter = new events.EventEmitter();emitter.on('fire', (word) => {  console.log(word)});emitter.emit('fire', 'Ready!');emitter.emit('fire', 'Aim!');emitter.emit('fire', 'Fire!');

This code block:

  1. Imports the events module
  2. Creates a new emitter object
  3. Creates the listener for the ‘fire’ event that takes one argument
  4. Emits the ‘fire’ event with the argument of Ready!
  5. The emitter we created takes the argument from the emitter and logs it.
  6. Step 4 and 5 repeats with Aim! and Fire!

This is the expected and correct output:

Ready!
Aim!
Fire!

Other types of Event Emitters

There are many different modules, packages, frameworks, etc.. that all utilize event emitters in different ways.

Angular uses event emitters in the way we used above, and they also use them to pass triggers back and forth between parent and child components.

Node’s file system module fs uses them when creating streams. When a certain action happens in these streams, they emit events. Like this:

var fs = require(‘fs’);
var rs = fs.createReadStream(‘./somefile.txt’);
rs.on(‘open’, function () {
console.log(‘File opened’);
});

In the code block above, we create a read stream and then create an event listener to read from the events that the stream emits. That way when the file is opened, instead of just waiting forever for it to open, we can just create that listener to be invoked when it is opened.

Conclusion

Event emitters and listeners are crucial to NodeJS development, and many other programming languages development. They are very useful when you have some function that needs to execute “whenever this other thing happens”, without requiring that function to finish or even work for that matter.

--

--

Stephen Boyd
The Startup

A software engineer who loves to learn, and wishes to spread any knowledge possible.