-
-
Save mudge/5830382 to your computer and use it in GitHub Desktop.
/* Polyfill indexOf. */ | |
var indexOf; | |
if (typeof Array.prototype.indexOf === 'function') { | |
indexOf = function (haystack, needle) { | |
return haystack.indexOf(needle); | |
}; | |
} else { | |
indexOf = function (haystack, needle) { | |
var i = 0, length = haystack.length, idx = -1, found = false; | |
while (i < length && !found) { | |
if (haystack[i] === needle) { | |
idx = i; | |
found = true; | |
} | |
i++; | |
} | |
return idx; | |
}; | |
}; | |
/* Polyfill EventEmitter. */ | |
var EventEmitter = function () { | |
this.events = {}; | |
}; | |
EventEmitter.prototype.on = function (event, listener) { | |
if (typeof this.events[event] !== 'object') { | |
this.events[event] = []; | |
} | |
this.events[event].push(listener); | |
}; | |
EventEmitter.prototype.removeListener = function (event, listener) { | |
var idx; | |
if (typeof this.events[event] === 'object') { | |
idx = indexOf(this.events[event], listener); | |
if (idx > -1) { | |
this.events[event].splice(idx, 1); | |
} | |
} | |
}; | |
EventEmitter.prototype.emit = function (event) { | |
var i, listeners, length, args = [].slice.call(arguments, 1); | |
if (typeof this.events[event] === 'object') { | |
listeners = this.events[event].slice(); | |
length = listeners.length; | |
for (i = 0; i < length; i++) { | |
listeners[i].apply(this, args); | |
} | |
} | |
}; | |
EventEmitter.prototype.once = function (event, listener) { | |
this.on(event, function g () { | |
this.removeListener(event, g); | |
listener.apply(this, arguments); | |
}); | |
}; |
Hello, this is actually amazing. What license do you release this under?
This was extracted from my Promise library Pacta and, as such, is released under the BSD 3-clause license.
@undecidedapollo and @coldsilk:
There seems to be a problem with the once/removeListener function. When the event is emitted and the listener is called, it calls remove. The remove function splices the array stored at this.event[eventString] while the emit function is doing a forEach on the same array. This splice modifies the array while it is being iterated against, and causes the forEach to skip the next listener.
It has been a while since I wrote this but I believe this is why emit
takes a shallow copy of the list of listeners on line 55 using slice
so that the loop is unaffected by removeListener
modifying the underlying events.
You can add simple overrides by returning true or false to stop propagation, e.g. return true to stop all other events before it.