问题
I realise that nodejs has a powerful EventEmitter constructor which allows you to emit events. However, what EventEmitter is missing is a way for the event emitter to see what the listeners returned.
This is the functionality I am after:
e = new FantasticEventEmitter();
e.on( 'event1', function( param1, param2, cb ){
console.log("First listener called...")
cb( null, 10 );
});
e.on( 'event1', function( param2, param2, cb ){
console.log("Ah, another listener called!");
cb( null, 20 );
});
e.emit( 'event1', 'firstParameter', 'secondParameter', function( err, res ){
console.log("Event emitted, now res will be [ 10, 20]");
});
Basically, I want listeners to be able to register, getting called when an event is fired up, and:
- Listeners to be passed a callback parameter. the callback will "collect" the results
- Emitters to have a callback, which will get called with the result collections
Is there a library that does this already, before I reinvent the wheel?
回答1:
There is no easy way to do it. To allow what I asked for, I wrote this GutHub module:
EventEmitterCollector.
Enjoy...
回答2:
Correct me if I am wrong but I don't think it should be. Event Emitter should not return callback results. Eventemiiters are an alternative to asynchronous function calls, if you use them correctly. You should not try to combine them and complicate stuff.
If you use them properly you can do what you want without async. There is no generalized way with eventemitter. Here is how I would do it :
- Event
incoming
: process the parameters and triggerstepn
in any fashion. - Event
stepn
: different for each step, do each step and at end callcollect
or call another intermediate step. - Event
collect
: store the outputs check for completion and calldone
when finished. - Event
done
: final callback (can be done in thecollect
itself).
This is totally my opinion/what i learned : asynchronous callbacks are the end result of internally evented execution. If you were to implement a async job at low-level, this is how you would do it. At high level with function callbacks and stuff, you would use async
.
回答3:
Maybe I'm misinterpreting your question, but your desired result code from your original question should just work. You can pass in a callback function as a parameter. EventEmitter instances you define can take callback arguments already. I made an example that shows how to do what you wanted with little change to your original.
var EventEmitter = require('events').EventEmitter;
var e = new EventEmitter();
// first listener
e.on('whatever', function(x,cb) {
console.log('first listener');
cb(10);
});
// second listener
e.on('whatever', function(x,cb) {
console.log('second listener');
cb(20);
});
// emit logic
var res = [];
e.emit('whatever', 'parameter', function(val) {
res.push(val);
});
console.log('Event emitted, now res will be [' + res.join(',') + ']');
来源:https://stackoverflow.com/questions/19214723/eventemitter-implementation-that-allows-you-to-get-the-listeners-results