Qi Events
http://drkibitz.github.io/qi-events/
A no nonsense event API (BASED ON Backbone.Events).
Goals
- Maintain a no nonsense event dispatching/emitting/triggering API.
- Test it.
- Find a happy medium between simplicity, speed, and usage.
- Should be able to perform well in high performance situations.
- Allow for the most common use cases, but within reason to maintain high performance.
- Embrace CommonJS Module format
- Allow for UglifyJS and Closure Compiler with ADVANCED_OPTIMIZATIONS.
- Allow for use as the basis of other event implmentations (scenegraph)
Usage
There are just 4 main methods to remember.
Use the mixin method to allow any object to trigger events.
require('qi-events').mixin({});
.on('myevent', console.log, console)
.trigger('myevent', 'something')
.trigger('myevent', 'something', 'something')
.trigger('myevent', 'something', 'something', 'darkside');
// > something
// > something something
// > something something darkside
Mixin into any prototype object.
var events = require('qi-events');
function MyEmitter() {}
events.mixin(MyEmitter.prototype);
var emitter = new MyEmitter();
emitter
.on('myevent', console.log, console)
.trigger('myevent', 'something', 'something', 'darkside');
// > something something darkside
Extend the provided class.
var Events = require('qi-events').Events;
function MyEmitter() {}
MyEmitter.prototype = Object.create(Events.prototype, {
constructor: {value: MyEmitter}
});
var emitter = new MyEmitter();
emitter
.on('myevent', console.log, console)
.trigger('myevent', 'something', 'something', 'darkside');
// > something something darkside
Use the module itself as a central dispatcher.
require('qi-events');
.once('myevent', console.log, console)
.trigger('myevent', 'something', 'something', 'darkside');
// > something something darkside
Changes since Backbone.Events
Backbone.js 0.9.10
(c) 2010-2013 Jeremy Ashkenas, DocumentCloud Inc.
Backbone may be freely distributed under the MIT license.
For all details and documentation:
http://backbonejs.org
- Added "use strict"
- Converted to CommonJS module
- Module is a constructor that can be used with class inheritence
Removed very minor dependencies on underscore.js and Backbone.js
- Added mixin method to replace Backbone mixin functionality
- Underscore was only used for slice, just using the native method
Completely removed listenTo(), listenToOnce(), and stopListening() methods
- Change eventsApi() to accept an array of event names
Change eventsApi() to receive function references instead of "action" strings
- This is a micro optimization and allows better obfuscation
trigger() no longer calls eventsApi(), this is a very rare (and mostly unnecessary) use case that can be avoided
- Optimization is important when triggering, but convenience is important when adding and removing
With trigger not using eventsApi(), it allowed further optimizations on eventsApi() and trigger()
- Removed ctx property from _events[name] object, just use context property instead
- Fixed lint errors in the process
Added aStart argument to triggerEvents() as a logical slice removing slice call for most cases
Why not EventEmitter?
So I think we already have four separate versions of EventEmitter at the time of writing this paragraph (April 2015). At this point in time, I am refusing to raise that count to five, or linking to any of them. Just to be clear, I am pretty sure I published this library when there were only two versions published, and I originally implemented my changes privately on top of Backbone.Events before it was broken up into parts. With all of this said, though I may be biased, I still prefer this library. If you are interested in how this API compares to the EventEmitter API, the following example should help.
var events = require('qi-events');
function EventEmitter25() {}
var proto = EventEmitter25.prototype;
proto.emit = events.trigger;
proto.on = proto.addListener = events.on;
proto.once = events.once;
proto.removeListener = events.off;
proto.listeners = function (event) {
if (!this._events || !this._events[event]) return [];
for (var i = 0, l = this._events[event].length, arr = new Array(l); i < l; i++) {
arr[i] = this._events[event][i].callback;
}
return arr;
};
proto.removeAllListeners = function (event) {
return events.off.call(this, event);
};
proto.setMaxListeners = function () {
return this;
};
module.exports = EventEmitter25;