Created
April 4, 2016 21:07
-
-
Save tuscen/72cc15910824bc0848dbc30730aeb1aa to your computer and use it in GitHub Desktop.
Event emitter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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