Custom event emitter classes let you create your own events and respond to them. This helps different parts of your program talk to each other easily.
Custom event emitter classes in Node.js
Start learning this pattern below
Jump into concepts and practice - no test required
or
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Introduction
Syntax
Node.js
const EventEmitter = require('events'); class MyEmitter extends EventEmitter { // custom methods or properties can go here } const emitter = new MyEmitter(); emitter.on('eventName', () => { console.log('Event happened!'); }); emitter.emit('eventName');
Use on to listen for an event.
Use emit to trigger the event and run all listeners.
Examples
Node.js
const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const emitter = new MyEmitter(); emitter.on('greet', () => { console.log('Hello!'); }); emitter.emit('greet');
Node.js
const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const emitter = new MyEmitter(); emitter.on('data', (msg) => { console.log('Received:', msg); }); emitter.emit('data', 'This is a message');
Node.js
const EventEmitter = require('events'); class MyEmitter extends EventEmitter { sendMessage(msg) { this.emit('message', msg); } } const emitter = new MyEmitter(); emitter.on('message', (msg) => { console.log('Message:', msg); }); emitter.sendMessage('Hi there!');
Sample Program
This program creates a TaskRunner class that emits 'start' and 'finish' events when running a task. Listeners print messages when these events happen. It simulates a task with a 1-second delay.
Node.js
const EventEmitter = require('events'); class TaskRunner extends EventEmitter { run(taskName) { console.log(`Starting task: ${taskName}`); this.emit('start', taskName); // Simulate task work with a timeout setTimeout(() => { this.emit('finish', taskName); console.log(`Finished task: ${taskName}`); }, 1000); } } const runner = new TaskRunner(); runner.on('start', (name) => { console.log(`Event: Task '${name}' has started.`); }); runner.on('finish', (name) => { console.log(`Event: Task '${name}' has finished.`); }); runner.run('CleanUp');
Important Notes
Always remove listeners if they are no longer needed to avoid memory leaks.
Use once if you want a listener to run only one time.
Event names are case-sensitive strings.
Summary
Custom event emitter classes help your code parts communicate by sending and listening to events.
You create a class extending EventEmitter, then use on and emit to handle events.
This pattern keeps your code organized and easy to extend.
Practice
1. What is the main purpose of creating a custom event emitter class in Node.js?
easy
Solution
Step 1: Understand event emitters
Event emitters let parts of a program send signals (events) and others listen and react to them.Step 2: Purpose of custom event emitter classes
Custom classes extend EventEmitter to organize and manage these events clearly.Final Answer:
To allow different parts of your program to communicate by sending and listening to events -> Option BQuick Check:
Event communication = C [OK]
Hint: Event emitters enable communication between code parts [OK]
Common Mistakes:
- Thinking event emitters speed up synchronous code
- Confusing event emitters with HTTP handling
- Believing event emitters replace all functions
2. Which of the following is the correct way to listen for an event named
data in a custom event emitter instance myEmitter?easy
Solution
Step 1: Identify the method to listen for events
Theonmethod is used to register a callback for an event.Step 2: Check other options
emittriggers events,listenandtriggerare not valid EventEmitter methods.Final Answer:
myEmitter.on('data', callback) -> Option AQuick Check:
Listen with on() = A [OK]
Hint: Use on() to listen, emit() to send events [OK]
Common Mistakes:
- Using emit() to listen instead of on()
- Using non-existent methods like listen() or trigger()
- Confusing event names with method names
3. Consider this code snippet:
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const emitter = new MyEmitter();
emitter.on('greet', name => console.log(`Hello, ${name}!`));
emitter.emit('greet', 'Alice');What will be printed when this code runs?medium
Solution
Step 1: Understand event registration
Theonmethod registers a listener for 'greet' that prints a greeting with the name.Step 2: Understand event emission
Theemitmethod triggers 'greet' with argument 'Alice', so the listener runs and prints the message.Final Answer:
Hello, Alice! -> Option CQuick Check:
Emit triggers listener output = B [OK]
Hint: emit() runs on() listeners with given arguments [OK]
Common Mistakes:
- Expecting event name or arguments to print directly
- Confusing emit() with on()
- Assuming error if no listener exists
4. What is wrong with this custom event emitter code?
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
const emitter = new MyEmitter();
emitter.emit('start');
emitter.on('start', () => console.log('Started'));medium
Solution
Step 1: Check event listener registration timing
The listener for 'start' is added after the event is emitted, so it misses the event.Step 2: Validate other options
emit() can be called without arguments, super() is optional if no constructor, and 'start' is a valid event name.Final Answer:
The event listener is registered after the event is emitted, so it won't run -> Option DQuick Check:
Listener after emit = no output = D [OK]
Hint: Register listeners before emitting events [OK]
Common Mistakes:
- Calling emit() before on() listener
- Thinking emit() needs arguments always
- Assuming constructor must call super() if none defined
5. You want to create a custom event emitter class that counts how many times an event named
ping is emitted. Which code correctly implements this behavior?hard
Solution
Step 1: Proper constructor and super() call
class PingCounter extends EventEmitter { constructor() { super(); this.count = 0; this.on('ping', () => this.count++); } } correctly callssuper()first in constructor, required before usingthis.Step 2: Correct event listener setup
class PingCounter extends EventEmitter { constructor() { super(); this.count = 0; this.on('ping', () => this.count++); } } usesthis.on('ping', () => this.count++)to increment count on each ping event.Step 3: Check other options for errors
class PingCounter extends EventEmitter { constructor() { this.count = 0; this.on('ping', () => this.count++); super(); } } callsthis.onbeforesuper(), causing error. class PingCounter extends EventEmitter { count = 0; on('ping', () => this.count++); } has invalid syntax outside constructor. class PingCounter extends EventEmitter { constructor() { super(); this.count = 0; this.emit('ping', () => this.count++); } } wrongly usesemitinstead ofon.Final Answer:
class PingCounter extends EventEmitter { constructor() { super(); this.count = 0; this.on('ping', () => this.count++); } } -> Option AQuick Check:
super() first, then on() listener = A [OK]
Hint: Always call super() before using this in constructor [OK]
Common Mistakes:
- Calling this before super() in constructor
- Using emit() instead of on() to listen
- Placing on() calls outside constructor or methods
