Comparing version 0.0.1 to 0.0.2
@@ -21,2 +21,22 @@ var async = require('async'); | ||
}); | ||
// 'Invoke' an event, only calling the handler if there is EXACTLY one | ||
// listener. | ||
eventEmitter.invoke = function () { | ||
var emitter = this, | ||
args = Array.prototype.slice.call(arguments), | ||
name = args.shift(), | ||
callback = args.pop(), | ||
listeners = emitter.listeners(name); | ||
if (!listeners.length) { | ||
callback(new Error('Tried to invoke `' + name + '` but there were no listeners')); | ||
} | ||
else if (listeners.length > 1) { | ||
callback(new Error('Tried to invoke `' + name + '` but there were ' + listeners.length + ' listners')); | ||
} | ||
else { | ||
asyncApply(emitter, listeners.pop(), args, callback); | ||
} | ||
}; | ||
}; | ||
@@ -36,19 +56,16 @@ | ||
function asyncApply (thisArg, fn, args, done) { | ||
var count = countArgs(fn); | ||
if (count <= args.length) { | ||
done(null, fn.apply(thisArg, args)); | ||
} | ||
else { | ||
fn.apply(thisArg, args.slice(0).concat([done])); | ||
} | ||
} | ||
function mapHandlers (emitter, name, args) { | ||
return emitter.listeners(name).map(function (listener) { | ||
return function (done) { | ||
var count = countArgs(listener), | ||
handlerArgs = args.slice(0), | ||
result = null; | ||
if (count <= args.length) { | ||
result = listener.apply(emitter, handlerArgs); | ||
done(null, result); | ||
} | ||
else { | ||
handlerArgs.push(done); | ||
listener.apply(emitter, handlerArgs); | ||
} | ||
}; | ||
return asyncApply.bind(emitter, emitter, listener, args); | ||
}); | ||
} |
{ | ||
"name": "eventflow", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"description": "Flow control for your event emitters", | ||
@@ -5,0 +5,0 @@ "main": "eventflow.js", |
@@ -12,3 +12,3 @@ EventFlow | ||
`on()` and `emit()` can get you pretty far, but wouldn't it be great if you | ||
could run your event handlers asynchronously, with a continuation callback. | ||
could run your event handlers asynchronously, with a continuation callback? | ||
@@ -117,3 +117,37 @@ **EventFlow** adds the flow-controlly-goodness of | ||
Invoke | ||
------ | ||
EventFlow also exposes the method `emitter.invoke(event, [args...], callback)`. | ||
Invoke executes using the following rules: | ||
1. There must be EXACTLY one listener for the event. Otherwise the callback | ||
is called with an error. | ||
2. The listener can `return` a value and if so, callback is called with `callback(err, value)`. | ||
3. The listener can accept a continuation callback and if so, that function should | ||
be called with `(err, [value])`. | ||
Think of 'invoke' as in-app RPC via an EventEmitter. Instead of passing | ||
functions around your app in `options` objects, you can invoke them instead. | ||
**Example** | ||
```js | ||
emitter.on('add', function(a, b) { | ||
return a + b; | ||
}); | ||
emitter.invoke('add', 1, 2, function(err, value) { | ||
console.log(value); | ||
// 3 | ||
}); | ||
emitter.on('subtract', function(a, b, callback) { | ||
callback(null, a - b); | ||
}); | ||
emitter.invoke('subtract', 3, 2, function(err, value) { | ||
console.log(value); | ||
// 1 | ||
}); | ||
``` | ||
Developed by [Terra Eclipse](http://www.terraeclipse.com) | ||
@@ -120,0 +154,0 @@ -------------------------------------------------------- |
@@ -109,3 +109,2 @@ var eventflow = require('../'), | ||
}); | ||
}); | ||
@@ -136,3 +135,77 @@ | ||
}); | ||
}); | ||
describe('invoke', function () { | ||
var emitter; | ||
beforeEach(function () { | ||
emitter = new EventEmitter(); | ||
}); | ||
it('should cause an error if there are no listeners', function (done) { | ||
emitter.invoke('timestamp', function (err, timestamp) { | ||
assert(err); | ||
done(); | ||
}); | ||
}); | ||
it('should cause an error if there are more than one listeners', function (done) { | ||
emitter.on('timestamp', function () { | ||
return new Date().getTime(); | ||
}); | ||
emitter.on('timestamp', function () { | ||
return new Date().getTime(); | ||
}); | ||
emitter.invoke('timestamp', function (err, timestamp) { | ||
assert(err); | ||
done(); | ||
}); | ||
}); | ||
it('should work when there is exactly one synchronous listner', function (done) { | ||
var timestamp = new Date().getTime(); | ||
emitter.on('timestamp', function () { | ||
return timestamp; | ||
}); | ||
emitter.invoke('timestamp', function (err, value) { | ||
assert.ifError(err); | ||
assert(value, timestamp); | ||
done(); | ||
}); | ||
}); | ||
it('should work when there is exactly one asynchronous listener', function (done) { | ||
var timestamp = new Date().getTime(); | ||
emitter.on('timestamp', function (callback) { | ||
callback(null, timestamp); | ||
}); | ||
emitter.invoke('timestamp', function (err, value) { | ||
assert.ifError(err); | ||
assert(value, timestamp); | ||
done(); | ||
}); | ||
}); | ||
it('should work with arguments', function (done) { | ||
emitter.on('add', function (a, b) { | ||
return a + b; | ||
}); | ||
emitter.invoke('add', 1, 2, function (err, value) { | ||
assert.ifError(err); | ||
assert(value, 3); | ||
done(); | ||
}); | ||
}); | ||
it('should work with arguments, asynchronously', function (done) { | ||
emitter.on('subtract', function (a, b, callback) { | ||
callback(null, a - b); | ||
}); | ||
emitter.invoke('subtract', 3, 2, function (err, value) { | ||
assert.ifError(err); | ||
assert(value, 1); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
12890
239
179