Node.js Fundamentals

Learn Node.js from scratch including core concepts, modules, and basic server development.

beginner Backend Development 5 hours

Chapter 9: Events and EventEmitter

Chapter 9 of 15

Chapter 9: Events and EventEmitter

9.1 EventEmitter

Node.js is built on an event-driven architecture. EventEmitter enables objects to emit and listen to events.

const EventEmitter = require('events');

// Create event emitter instance
const emitter = new EventEmitter();

// Listen for event
emitter.on('greet', (name) => {
    console.log(`Hello, ${name}!`);
});

// Emit event
emitter.emit('greet', 'John'); // Output: Hello, John!

Event Methods:

  • on(): Register event listener
  • once(): Listen once, then remove
  • emit(): Trigger event
  • removeListener(): Remove specific listener
  • removeAllListeners(): Remove all listeners
// Multiple listeners
emitter.on('data', (data) => {
    console.log('Listener 1:', data);
});

emitter.on('data', (data) => {
    console.log('Listener 2:', data);
});

emitter.emit('data', 'test');
// Output:
// Listener 1: test
// Listener 2: test

// Listen once
emitter.once('connect', () => {
    console.log('Connected');
});

emitter.emit('connect'); // Output: Connected
emitter.emit('connect'); // No output (listener removed)

9.2 Creating Custom Event Emitters

Extend EventEmitter to create custom event-driven classes.

const EventEmitter = require('events');

class User extends EventEmitter {
    constructor(name) {
        super();
        this.name = name;
    }
    
    login() {
        // Emit login event
        this.emit('login', { user: this.name, time: new Date() });
    }
    
    logout() {
        this.emit('logout', { user: this.name });
    }
}

// Use custom emitter
const user = new User('John');

user.on('login', (data) => {
    console.log(`${data.user} logged in at ${data.time}`);
});

user.login(); // Output: John logged in at [timestamp]

9.3 Event Patterns

Common patterns for using events in Node.js.

Error Events:

emitter.on('error', (err) => {
    console.error('Error occurred:', err);
});

// If error event has no listeners, Node.js will throw
emitter.emit('error', new Error('Something went wrong'));

Event Chaining:

emitter
    .on('start', () => console.log('Started'))
    .on('process', () => console.log('Processing'))
    .on('end', () => console.log('Ended'));

emitter.emit('start');
emitter.emit('process');
emitter.emit('end');

9.4 Events in Node.js Core

Many Node.js core modules use EventEmitter.

const fs = require('fs');

// File streams are event emitters
const readStream = fs.createReadStream('file.txt');

readStream.on('data', (chunk) => {
    console.log('Received chunk:', chunk);
});

readStream.on('end', () => {
    console.log('File read complete');
});

readStream.on('error', (err) => {
    console.error('Error:', err);
});