FrontendInterviews.dev

Loading problem…

136. Event Emitter III - Async + Middleware

Hard•

This problem builds on event-emitter-ii. Complete that first, then load your solution to continue.

Implement an advanced EventEmitter equipped with asynchronous execution, middleware interception, event batching, history tracking, and wildcard subscription matching.

Modern applications often require high-level pub/sub systems capable of tracking telemetry, intercepting payloads, and handling network-bound events.

Requirements

Implement the EventEmitter class:

class EventEmitter {
  on(event, handler) {}
  use(middleware) {}
  emit(event, ...args) {}
  getHistory() {}
}

Core Mechanics

  • Async Emit: emit(event, ...args) must return a Promise that resolves to an array of the return values of all triggered handlers.
  • Async Handlers: Handlers may be async functions; emit must await all of them before resolving.
  • Middleware: use(middleware) registers a global middleware function (event, args) => void. Middleware runs purely before any handlers and can mutate the args array in place to influence the payload passed to specific handlers.
  • Event History: getHistory() returns an array of objects { event, args } detailing all events emitted sequentially thus far.
  • Wildcard Listeners: Support two types of wildcards:
  • *: Receives all emitted events.
  • prefix:* (e.g. user:*): Receives all events starting with prefix:.

Example Usage

const ee = new EventEmitter();

// 1. Middleware mutation
ee.use((event, args) => { 
  if (typeof args[0] === 'number') args[0] *= 10;
});

// 2. Wildcard listening
ee.on('user:*', (val) => `User: ${val}`);

// 3. Async result gathering
ee.on('user:login', async (score) => {
  await sleep(10);
  return score + 5;
});

const results = await ee.emit('user:login', 10);
// results => ["User: 100", 105] (Note: 10 became 100 via middleware)

Constraints

  • Support async handlers
  • Support middleware
  • Support event batching
  • Track event history
  • Support wildcard listeners
Accepted19/22|Acceptance Rate86.4%