Skip to content

Instantly share code, notes, and snippets.

@kevireilly
Created January 25, 2013 05:20
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 kevireilly/4631979 to your computer and use it in GitHub Desktop.
Save kevireilly/4631979 to your computer and use it in GitHub Desktop.
EventHook: Simple library for modifiable EventEmitters
/*
* ____ _ _ ____ _ _ ___ _ _ ____ ____ _ _
* |___ | | |___ |\ | | |__| | | | | |_/
* |___ \/ |___ | \| | | | |__| |__| | \_
*
* Simple library for modifiable EventEmitters
*
* Depends on the async module
* https://github.com/caolan/async
* npm install async
*
* -------------------------------------------
* -- USAGE --------------------------------
* -------------------------------------------
* var Events = require('events');
* var EventHook = require('./eventhook.js');
* var eventhook = new Events.EventEmitter();
*
* eventhook.on('modifiable', function(modifyMe, callback){
* var error = false;
* modifyMe++;
* callback(error, modifyMe);
* });
* eventhook.on('modifiable', function(modifyMe, callback){
* var error = false;
* modifyMe++;
* callback(error, modifyMe);
* });
*
* var toBeModified = 1;
* eventhook.hook('modifiable', toBeModified, function(error, result){
* if (error) throw new Error('Issue with EventHook listener: ' + result);
* // The value should end up as 3
* console.log(result);
* // Add more listeners for more
* // IE: 3 listeners should result
* // in the value being 4
* });
*
*
* -------------------------------------------
* -- ROADMAP ------------------------------
* -------------------------------------------
* o Accept more than one argument
* (You can use an object for now)
*
*/
'use strict'; /*jshint node: true*/
var EventEmitter = require('events').EventEmitter;
var async = require('async');
// Setup the hook prototype for EventEmitters
EventEmitter.prototype.hook = function(type, arg, callback) {
// Check for missing requirements in development environment only
if (process.env.NODE_ENV !== 'production') {
if (!type) throw new Error('Type is required');
if (!arg) throw new Error('Arg is required');
if (!callback) throw new Error('Callback is required');
}
// No event listeners? Return the original argument
if (!this._events) return callback(false, arg);
var listeners = this._events[type];
if (!listeners) return callback(false, arg);
// This is because the first function in an
// async.waterfall needs to pass the argument
var passArg = function(cb) {
cb(false, arg);
};
// Add passArg to the listeners array
if (Array.isArray(listeners)) {
listeners.unshift(passArg);
} else {
// async.waterfall requires an array
// Listeners is not an array when
// there is only 1 listener
listeners = [passArg, listeners];
}
// Pass existing listeners to async.waterfall
// Allows each listener to modify the argument
async.waterfall(listeners, function(err, result){
// Return the final result to the original callback
return callback(err, result);
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment