Skip to content

Instantly share code, notes, and snippets.

@tim-smart
Last active December 18, 2015 15:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tim-smart/5801765 to your computer and use it in GitHub Desktop.
Save tim-smart/5801765 to your computer and use it in GitHub Desktop.
var vm = require('vm')
var EventEmitter = require('events').EventEmitter
// ====
/**
* Supermitter - A compile-on-the-fly event emitter
*
* @constructor
*/
function Supermitter () {
this._events = {}
this._counter = 0
}
var proto = Supermitter.prototype
/**
* on - Listen to an event
*
* @param String event
* @param Function fn
* @return Supermitter
*/
proto.on = function on (event, fn) {
this._events[event] || (this._events[event] = [])
this._events[event].push(this._assign(fn))
this.recompile()
return this
}
/**
* recompile - Re-compiles the emit function
*
* @param String event
* @return Supermitter
*/
proto.recompile = function recompile () {
var events = null // Array
var out = null // Array
var method = null // String
var key = null // String
// Generate emit()
out =
[ '(function (event, data) {'
, ' switch (event) {'
]
events = Object.keys(this._events)
for (var i = 0, il = events.length; i < il; i++) {
key = events[i]
out.push(' case "' + key + '":')
for (var j = 0, jl = this._events[key].length; j < jl; j++) {
method = this._events[key][j]
out.push(' this.' + method + '(data)')
}
out.push(' return true')
}
out.push(' }', ' return false', '})')
out = out.join("\n")
this.emit = vm.runInThisContext(out)
events = out = method = key = null
return this
}
/**
* _assign - Assign a unique name to a function
*
* @param Function fn
* @return String
*/
proto._assign = function assign (fn) {
var method = '__fn' + this._counter
this[method] = fn
;++this._counter
return method
}
/**
* emit - To be replaced with generated function
*
* @param String event
* @param Mixed data
* @return Boolean
*/
proto.emit = function emit (event, data) {
return false
}
// ====
var e = new Supermitter
var start = null
e.on('test:event', function (data) {})
e.on('test:event', function (data) {})
e.on('test:event', function (data) {})
e.on('test:event', function (data) {})
e.on('testing', function () {})
start = Date.now()
for (var i = 0; i < 10000000; i++) {
e.emit('test:event', [1, 2, 3])
}
console.log('Superemitter:multiple', Date.now() - start)
start = Date.now()
for (var i = 0; i < 10000000; i++) {
e.emit('testing', [1, 2, 3])
}
console.log('Supermitter:single', Date.now() - start)
// --
var ee = new EventEmitter
ee.on('test:event', function (data) {})
ee.on('test:event', function (data) {})
ee.on('test:event', function (data) {})
ee.on('test:event', function (data) {})
ee.on('testing', function () {})
start = Date.now()
for (var i = 0; i < 10000000; i++) {
ee.emit('test:event', [1, 2, 3])
}
console.log('EventEmitter:multiple', Date.now() - start)
start = Date.now()
for (var i = 0; i < 10000000; i++) {
ee.emit('testing', [1, 2, 3])
}
console.log('EventEmitter:single', Date.now() - start)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment