Node.js is event-driven — many core APIs emit events that you listen for with callbacks.

EventEmitter

  import { EventEmitter } from 'events';

const emitter = new EventEmitter();

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

emitter.emit('greet', 'Alice'); // Hello, Alice!
  

Multiple Listeners

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

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

once — Run Only Once

  emitter.once('connect', () => console.log('Connected!'));
emitter.emit('connect'); // Connected!
emitter.emit('connect'); // (nothing)
  

Removing Listeners

  function handler() { console.log('Event fired'); }

emitter.on('event', handler);
emitter.off('event', handler); // or removeListener
  

Custom Event Classes

  import { EventEmitter } from 'events';

class OrderService extends EventEmitter {
    createOrder(items) {
        const order = { id: Date.now(), items, status: 'pending' };
        this.emit('order:created', order);
        return order;
    }

    completeOrder(orderId) {
        this.emit('order:completed', orderId);
    }
}

const orders = new OrderService();

orders.on('order:created', (order) => {
    console.log('New order:', order.id);
});

orders.on('order:completed', (id) => {
    console.log('Order completed:', id);
});

orders.createOrder(['book', 'pen']);
  

Built-in Events

  import http from 'http';

const server = http.createServer();
server.on('request', (req, res) => res.end('OK'));
server.on('error', (err) => console.error(err));
server.on('listening', () => console.log('Server started'));
  

Error Events

Unhandled 'error' events crash the process:

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

// Or use captureRejections with async listeners
  

Event Loop Phases (Overview)

  1. TimerssetTimeout, setInterval
  2. Pending callbacks — I/O callbacks
  3. Poll — retrieve new I/O events
  4. ChecksetImmediate callbacks
  5. Closeclose events
  console.log('1');
setTimeout(() => console.log('2'), 0);
setImmediate(() => console.log('3'));
process.nextTick(() => console.log('4'));
console.log('5');
// 1, 5, 4, 2, 3 (approximate)
  

EventEmitter is the foundation of Node.js’s asynchronous, non-blocking design.