Skip to content

Instantly share code, notes, and snippets.

@tuscen
Created April 4, 2016 21:07
Show Gist options
  • Save tuscen/72cc15910824bc0848dbc30730aeb1aa to your computer and use it in GitHub Desktop.
Save tuscen/72cc15910824bc0848dbc30730aeb1aa to your computer and use it in GitHub Desktop.
Event emitter
const events = Symbol("events");
class EventEmitter {
constructor() {
this[events] = new Map();
}
addListener(event, callback, once = false) {
this[events].has(event) || this[events].set(event, new Map());
const listeners = this[events].get(event);
listeners.set(callback, once)
}
on(...args) {
this.addListener(...args);
}
once(event, callback) {
this.on(event, callback, true);
}
emit(event, ...args) {
if (!this[events].has(event)) {
return;
}
const listeners = this[events].get(event);
const currentListeners = [];
for (let listener of listeners.entries()) {
currentListeners.push(listener);
}
currentListeners.forEach(([listener, once]) => {
listener.apply(null, args);
if (once) {
this.removeListener(event, listener);
}
});
}
removeListener(event, listener) {
if (!this[events].has(event)) {
return;
}
const listeners = this[events].get(event);
if (!listener) {
listeners.clear();
this[events].delete(event);
} else {
listeners.delete(listener);
}
}
listeners(event) {
const listeners = this[events].get(event);
const result = [];
for (let [listener] of listeners.entries()) {
result.push(listener);
}
return result;
}
}
class Observer {
constructor(id, subject) {
this.id = id;
this.subject = subject;
this.subject.on('change', data => this.onChange(data));
}
onChange(data) {
console.log(`${this.id} notified of change:`, data);
}
}
const observable = new EventEmitter();
const observers = new Array(5)
.fill(null)
.map((_, index) => new Observer(index, observable));
observable.emit('change', { someKey: 'some very important data' });
// =>
// 0 notified of change: { someKey: 'some very important data' }
// 1 notified of change: { someKey: 'some very important data' }
// 2 notified of change: { someKey: 'some very important data' }
// 3 notified of change: { someKey: 'some very important data' }
// 4 notified of change: { someKey: 'some very important data' }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment