dispatcherjs
v0.5.2
Published
An event emitter implementation that supports namespaces and callback dependency. Works in Node.js and browser.
Downloads
189
Readme
DispatcherJS
An event emitter implementation that supports namespaces and callback dependency. Works in Node.js and browser.
Features
- Namespaces
- Callback dependency
- Multi-tier event naming
- Compatible with Node.js EventEmitter
- Works on browser without any dependency
Installation
As an NPM module
npm install dispatcherjs
or as a bower component
bower install dispatcherjs
Usage
If you already have native Node.js EventEmitter implemented in your system, you can safely replace it with DispatcherJS. It won't break. When an error occurs in DispatcherJS, it throws an Error
and stops execution. The difference is how DispatcherJS is initialized. Which is:
var Dispatcher = require('dispatcherjs')
, dispatcher = new Dispatcher();
dispatcher.addListener(event[, dependencies], listener)
dispatcher.on(event[, dependencies], listener)
Adds a listener for a specified event.
dispatcher.on('request', function (context) {
console.log('We have received a request.');
});
A namespace can also be specified with or without an event using . delimiter. For example let's assume there is a request for API. A .api
namespace can be added to provide more specific naming.
dispatcher.on('request.api', function (context) {
console.log('We have received a request for API.');
});
Now let's specify a .static
namespace for to define request for static files.
dispatcher.on('request.static', function (context) {
console.log('We have received a request for static files.');
});
Now when a request
event is emitted both listeners will run but if request.api
event is emitted only the first one will run.
We can also listen a namespace:
dispatcher.on('.static', function (context) {
console.log('We have received an event for "static" namespace.');
});
Listening All Events
Specifying * as event name will let the listener listen for all.
dispatcher.on('*', function() {
console.log('We are listening everyone');
});
Multi-tier Event Names
Multi-tiering is useful when using a namespace is not specific enough to define a listener. For example if API requests are for user resources, a : delimiter can be used.
dispatcher.on('request:user.api', apiFunc);
Or something even more specific like adding a userId.
dispatcher.on('request:user:491283812.api', apiFunc);
Any listener that listens for request:user will receive both events but a listener for request:user:491283812 won't receive the first one.
Callback Dependency
A list of dependencies can be specified for every listener to ensure it is executed in right time. For example let's assume there is a listener of foo that needs to be executed after every foo.bar and foo.bazz listeners. This can be achieved like following:
dispatcher.on('foo', ['.bar', '.baz'], someFunc);
or when there is only one dependency:
dispatcher.on('foo', '.bar', someFunc);
Things can get complicated if listeners are doing asynchronous operations. Dispatcher has a solution for that using promises. An async listener should return a Promise object to ensure listeners depending on this listener will be executed after async operation is done. Example with standard EcmaScript 6 Promise:
dispatcher.on('foo', function () {
return new Promise(function someAsyncFunction() {
// Do asynchronous stuff
});
});
Stop Propagation
A function accessible through context parameter of listeners. It prevents other listeners that are bound to this event from being executed. The listener that .stopPropagation() called from will continue it's execution as expected.
dispatcher.on('foo', function (context) {
context.stopPropagation();
// Do stuff
});
dispatcher.once(event[, dependencies], listener)
Same with .on() but it is removed after executed once.
dispatcher.removeListener(event[, listener])
dispatcher.off(event[, listener])
Removes given listener from dispatcher or removes all listeners that listens given event.
function someHandler(context) {
console.log('We have received a request.');
}
dispatcher.off('message', someHandler);
or
dispatcher.off('message');
dispatcher.removeAllListeners([event])
Removes all listeners, or those of the specified event.
dispatcher.listeners([event])
Returns all listeners or those of the specified event.
dispatcher.emit(event[, arguments...])
Emits an event and runs all listeners matches specified event. Optionally given arguments will be passed to listeners. Example:
dispatcher.emit('message');
Now with arguments:
dispatcher.emit('message', 'arg1', 2, true);
Arguments can be received like below
dispatcher.on('message', function (context) {
console.log('Here are the arguments' + context.arguments);
});
More complex events can also be emitted like:
dispatcher.emit('message:fromUser:123456.api');
An event without event name will not be emitted. Dispatcher will not emit a .api event which has only a namespace.
dispatcher.applyEmit(event[, arguments...])
A convenience function that returns a function which when called emits an event with given event name and parameters. So,
dispatcher.applyEmit('message')();
is same with
dispatcher.emit('message');
Useful when an emit function needs to be chained with some other function. For example you want a buttonClick event to be emitted when every time a button is clicked:
$('button').on('click', dispatcher.applyEmit('buttonClick'));
dispatcher.setMaxListeners(limitNumber)
Limits number of listeners that can be assigned to a an event. Default is 10.
Auto-emitted Events
There are two events emitted automatically. One 'newListener' which will be emitted when there is a new listener added to dispatcher. The other one is 'removeListener' which will be emitted when a listener is removed. Only exception to this is when dispatcher.removeAllListeners() called because, you know, all listeners are removed including removeListener listeners.