diff --git a/lib/utils/asyncemitter.js b/lib/utils/asyncemitter.js index 5fac07e7..06e21734 100644 --- a/lib/utils/asyncemitter.js +++ b/lib/utils/asyncemitter.js @@ -89,7 +89,7 @@ AsyncEmitter.prototype._push = function _push(type, handler, once) { this._events[type].push(new Listener(handler, once)); - this.tryEmit('newListener', type, handler); + this.emit('newListener', type, handler); }; /** @@ -107,7 +107,7 @@ AsyncEmitter.prototype._unshift = function _unshift(type, handler, once) { this._events[type].unshift(new Listener(handler, once)); - this.tryEmit('newListener', type, handler); + this.emit('newListener', type, handler); }; /** @@ -143,7 +143,7 @@ AsyncEmitter.prototype.removeListener = function removeListener(type, handler) { if (listeners.length === 0) delete this._events[type]; - this.tryEmit('removeListener', type, handler); + this.emit('removeListener', type, handler); }; /** @@ -216,6 +216,69 @@ AsyncEmitter.prototype.listenerCount = function listenerCount(type) { return listeners.length; }; +/** + * Emit an event synchronously. + * @method + * @param {String} type + * @param {...Object} args + * @returns {Promise} + */ + +AsyncEmitter.prototype.emit = function emit(type) { + var i, j, listeners, error, err, args, listener, handler; + + assert(typeof type === 'string', '`type` must be a string.'); + + listeners = this._events[type]; + + if (!listeners || listeners.length === 0) { + if (type === 'error') { + error = arguments[1]; + + if (error instanceof Error) + throw error; + + err = new Error('Uncaught, unspecified "error" event. (' + error + ')'); + err.context = error; + throw err; + } + return; + } + + for (i = 0; i < listeners.length; i++) { + listener = listeners[i]; + handler = listener.handler; + + if (listener.once) { + listeners.splice(i, 1); + i--; + } + + switch (arguments.length) { + case 1: + handler(); + break; + case 2: + handler(arguments[1]); + break; + case 3: + handler(arguments[1], arguments[2]); + break; + case 4: + handler(arguments[1], arguments[2], arguments[3]); + break; + default: + if (!args) { + args = new Array(arguments.length - 1); + for (j = 1; j < arguments.length; j++) + args[j - 1] = arguments[j]; + } + handler.apply(null, args); + break; + } + } +}; + /** * Emit an event. Wait for promises to resolve. * @method @@ -224,7 +287,7 @@ AsyncEmitter.prototype.listenerCount = function listenerCount(type) { * @returns {Promise} */ -AsyncEmitter.prototype.emit = co(function* emit(type) { +AsyncEmitter.prototype.fire = co(function* fire(type) { var i, j, listeners, error, err, args, listener, handler; assert(typeof type === 'string', '`type` must be a string.'); @@ -287,11 +350,18 @@ AsyncEmitter.prototype.emit = co(function* emit(type) { * @returns {Promise} */ -AsyncEmitter.prototype.tryEmit = co(function* tryEmit() { +AsyncEmitter.prototype.tryFire = co(function* tryFire(type) { try { yield this.emit.apply(this, arguments); } catch (e) { - ; + if (type === 'error') + return; + + try { + yield this.emit('error', e); + } catch (e) { + ; + } } });