← Wszystkie zadaniaJavaScript · Senior

EventEmitter

Napisz klasę EventEmitter z metodami:

on(event, listener) - subskrypcja; zwraca funkcję wypisania. off(event, listener) - wypisanie. once(event, listener) - subskrypcja na jedno wywołanie. emit(event, ...args) - wywołuje subskrybentów w kolejności zapisu i zwraca true, jeśli jacyś byli, w przeciwnym razie false.

Ten sam handler można zapisać dwa razy - wtedy jest wywoływany dwa razy. Jeśli subskrybent w trakcie emit wypisze innego, bieżący emit i tak wywoła wszystkich zapisanych w chwili jego rozpoczęcia.

Testy (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']);