Event Emitters

⭐ Interview Importance: HIGH
⏱️ Revision Time: 4 min

TL;DR

The EventEmitter class in Node.js is an implementation of the Observer Pattern. It allows objects to emit named events that cause previously registered listener functions to be called synchronously.

Mental Model

How It Works

  1. Registration: You use .on() or .addListener() to register a function to a specific event name.
  2. Emission: You use .emit() to trigger the event. All registered functions for that event are called synchronously in the exact order they were registered.
  3. Many core Node.js modules (like fs, http, stream) extend the EventEmitter class.

Example

const EventEmitter = require('events');

class UserService extends EventEmitter {
    createUser(name) {
        // ... DB logic here ...
        console.log(`User ${name} created in DB.`);
        
        // Emit an event
        this.emit('userCreated', name);
    }
}

const service = new UserService();

// Register a listener
service.on('userCreated', (name) => {
    console.log(`Sending welcome email to ${name}`);
});

service.createUser('Alice');
/* Output:
User Alice created in DB.
Sending welcome email to Alice
*/

Common Interview Questions

Is EventEmitter synchronous or asynchronous?

It is synchronous. When you call .emit(), the listener functions are executed immediately and sequentially before the code following the .emit() continues. If you want asynchronous behavior, you must explicitly use setImmediate or process.nextTick inside the listener.

What happens if an unhandled ‘error’ event is emitted?

If an EventEmitter emits an 'error' event and no listener is attached to it, Node.js will crash the application and print the stack trace. Always attach an .on('error', ...) listener.