← Alle AufgabenJavaScript · Senior

EventEmitter

Schreib eine Klasse EventEmitter mit diesen Methoden:

on(event, listener) abonniert und liefert eine Funktion zum Abmelden. off(event, listener) meldet ab. once(event, listener) abonniert für einen einzigen Aufruf. emit(event, ...args) ruft die Listener in der Reihenfolge der Anmeldung auf und liefert true, wenn es welche gab, sonst false.

Derselbe Listener kann zweimal angemeldet werden und wird dann zweimal aufgerufen. Meldet ein Listener während emit einen anderen ab, ruft das aktuelle emit trotzdem alle auf, die bei seinem Start angemeldet waren.

Tests (7)

  1. const e = new EventEmitter();
    const f = fn();
    e.on('msg', f);
    e.emit('msg', 1, 2);
    expect(f).toHaveBeenCalledWith(1, 2);
  2. const e = new EventEmitter();
    const a = fn();
    const b = fn();
    e.on('x', a);
    e.on('x', b);
    expect(e.emit('x')).toBe(true);
    expect(e.emit('y')).toBe(false);
    expect(a).toHaveBeenCalledTimes(1);
    expect(b).toHaveBeenCalledTimes(1);
  3. const e = new EventEmitter();
    const f = fn();
    e.on('x', f);
    e.off('x', f);
    e.emit('x');
    expect(f).toHaveBeenCalledTimes(0);
  4. const e = new EventEmitter();
    const f = fn();
    const unsubscribe = e.on('x', f);
    unsubscribe();
    e.emit('x');
    expect(f).toHaveBeenCalledTimes(0);
  5. const e = new EventEmitter();
    const f = fn();
    e.once('x', f);
    e.emit('x', 'a');
    e.emit('x', 'b');
    expect(f).toHaveBeenCalledTimes(1);
    expect(f).toHaveBeenLastCalledWith('a');
  6. const e = new EventEmitter();
    const f = fn();
    e.on('x', f);
    e.on('x', f);
    e.emit('x');
    expect(f).toHaveBeenCalledTimes(2);
  7. const e = new EventEmitter();
    const calls = [];
    const second = () => calls.push('second');
    const first = () => { calls.push('first'); e.off('x', second); };
    e.on('x', first);
    e.on('x', second);
    e.emit('x');
    e.emit('x');
    expect(calls).toEqual(['first', 'second', 'first']);