Minimal event emitter with once listeners
JavaScript
// Tiny event emitter: on/once/off/emit, with unsubscribe handles.
class Emitter {
#listeners = new Map();
on(event, listener) {
const list = this.#listeners.get(event) ?? new Set();
list.add(listener);
this.#listeners.set(event, list);
return () => this.off(event, listener);
}
once(event, listener) {
const wrapped = (...args) => {
this.off(event, wrapped);
listener(...args);
};
return this.on(event, wrapped);
}
off(event, listener) {
this.#listeners.get(event)?.delete(listener);
}
emit(event, ...args) {
for (const listener of [...(this.#listeners.get(event) ?? [])]) {
listener(...args);
}
}
}
// Usage
const bus = new Emitter();
const stop = bus.on('save', (file) => console.log('saved', file));
bus.once('save', () => console.log('first save only'));
bus.emit('save', 'notes.md');
bus.emit('save', 'todo.md');
stop();