FrontendPro

124Implement a memory-efficient event bus with lifecycle cleanup and leak detection

hardAbout 60 minutesCodingeventsmemory-leaksabortsignalarchitecture

Problem

A global event bus in a long-running single-page app is a classic source of memory leaks: components subscribe on mount, forget to unsubscribe, and every visit to a page adds another listener that keeps the old component alive.

Implement createEventBus({ maxListeners = 10, onLeak = () => {}, onError = (error) => console.error(error) } = {}) returning:

  • on(event, handler, { signal, owner, once } = {}): subscribe and return an unsubscribe function (safe to call twice).
    • With signal (an AbortSignal), unsubscribe automatically when it aborts; an already-aborted signal never subscribes.
    • With owner (any object, for example a component instance), the subscription is grouped under that owner.
    • With once, unsubscribe after the first call.
  • releaseOwner(owner): remove every subscription of that owner.
  • emit(event, payload): call the handlers in subscription order. A handler that throws must not stop the others; report the error with onError(error, event). Return the number of handlers called.
  • listenerCount(event) and events() (events that currently have listeners; empty ones must not linger).
  • Leak detection: when an event's listener count goes above maxListeners, call onLeak(event, count) once. Warn again only after the count has dropped back to the limit or below and then exceeded it again.

Owners are kept in a WeakMap, so the bus never keeps an owner object alive.

Try it yourself

Write your solution, run it, then submit to check it against the tests.

solution.jsJavaScript

Press Run or ⌘ Enter to execute your code.

Step-by-step

{ event, handler, once, active }. Store them in a Map from event name to a Set of subscriptions. A Set keeps insertion order and makes removal O(1).

Unlock the full solution

What's inside

  • Step-by-step
  • Approach
  • Solution
  • Complexity
  • Edge cases
  • Follow-up questions
  • Tests

Includes 2 code listings, 5 edge cases, 4 follow-up questions.

One-time payment by UPI, card or net banking. Launch price.

All 150 answersOne payment, yours forever