2013-10-29 49 views
1

我有以下代码。它基本上扩展了EventEmitter,所以它不是发布事件并忘记它,而是实际收集结果。使用异步和同步调用收集结果

我写它作为一个答案:EventEmitter implementation that allows you to get the listeners' results?

这段代码的问题在于,它假定每个听众是异步的。如果其中一个是异步的,那么async.series就会失败。

我的想法是与检查,如果它的最后一个参数是一个函数的函数来包装听众。它不是,它应该用一个类似于异步调用的函数来包装它。但是,我在做这件事情时失败了。

帮助?

var events = require('events'); 
var util = require('util'); 
var async = require('async'); 

// Create the enhanced EventEmitter 
function AsyncEvents() { 
    events.EventEmitter.call(this); 
} 
util.inherits(AsyncEvents, events.EventEmitter); 

// Just a stub 
AsyncEvents.prototype.onAsync = function(event, listener){ 
    return this.on(event, listener); 
} 

// Async emit 
AsyncEvents.prototype.emitAsync = function(){ 

    var event, 
    module, 
    results = [], 
    functionList = [], 
    args, 
    callback, 
    eventArguments; 

    // Turn `arguments` into a proper array 
    args = Array.prototype.splice.call(arguments, 0); 

    // get the `hook` and `hookArgument` variables 
    event = args.splice(0,1)[0]; // The first parameter, always the hook's name 
    eventArguments = args;  // The leftovers, the hook's parameters 

    // If the last parameter is a function, it's assumed 
    // to be the callback 
    if(typeof(eventArguments[ eventArguments.length-1 ]) === 'function'){ 
    callback = eventArguments.pop(); // The last parameter, always the callback 
    } 

    var listeners = this.listeners(event); 

    listeners.forEach(function(listener) { 

     // Pushes the async function to functionList. Note that the arguments passed to invokeAll are 
     // bound to the function's scope 
     functionList.push(function(done){ 
      listener.apply(this, Array.prototype.concat(eventArguments, done)); 
     }); 
    }); 
    callback ? async.series(functionList, callback) : async.series(functionList); 
} 

下面是测试一个简单的方法:

asyncEvents = new AsyncEvents(); 

asyncEvents.onAsync('one', function(paramOne1, done){ 
    done(null, paramOne1 + ' --- ONE done, 1'); 
}); 

asyncEvents.onAsync('one', function(paramOne2, done){ 
    done(null, paramOne2 + ' --- ONE done, 2'); 
}); 

// Uncomment this and async will fail 
//asyncEvents.onAsync('one', function(paramOne3, done){ 
// return paramOne3 + ' --- ONE done, 3' ; 
//}); 

asyncEvents.onAsync('two', function(paramTwo, done){ 
    done(null, 'TWO done, 1'); 
}); 


asyncEvents.emitAsync('one', 'P1', function(err, res){ 
    console.log(err); 
    console.log(res); 
}); 

asyncEvents.emitAsync('two', 'P2', function(err, res){ 
    console.log(err); 
    console.log(res); 
}); 

谢谢!

+0

至于其他[回应](http://stackoverflow.com/a/19218317/458093)的链接的问题说,事件处理程序的设计与模式“射后不理”。整个node.js平台就是这样设计的。 –

+0

有些情况下,“火和遗忘”不是你想要的。很多情况下。现在,已经说过了,请保留范围内的问题 - 即收集异步和同步功能的结果。谢谢。 – Merc

+0

如果您知道哪些功能是同步的,您可以简单地将它们包装在异步功能中。这可能比你想要做的更容易。 –

回答

1

它根本无法完成。故事结局。