2013-10-29 3 views
1

다음 코드가 있습니다. 기본적으로 EventEmitter를 확장하므로 이벤트를 내보내고 잊어 버리는 대신 실제로 결과를 수집합니다. 비동기 및 동기화 호출을 사용하여 결과 수집

나는이에 대한 답변으로 쓴 : EventEmitter implementation that allows you to get the listeners' results?

이 코드의 문제는 그것이 모든 리스너가 비동기 있다고 가정합니다. 그 중 하나가 비동기식이면 async.series는 단순히 실패합니다.

제 생각은 마지막 매개 변수가 함수인지 확인하는 함수로 리스너를 래핑하는 것입니다. 그렇지 않은 경우 비동기 호출과 비슷한 방식으로 작동하는 함수로 포장해야합니다. 그러나, 나는 이것을 비참하게하는 광고에 실패하고있다.

도움 말?

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); 
}); 

감사 :

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); 
} 

는 여기를 테스트 할 수있는 쉬운 방법입니다!

+0

연결된 질문에 대한 다른 [응답] (http://stackoverflow.com/a/19218317/458093)에 따르면 이벤트 처리기는 "화재 및 잊어"패턴으로 디자인되었습니다. 전체 node.js 플랫폼은 이런 식으로 설계되었습니다. –

+0

"화재와 잊기"가 원하는 것이 아닌 경우가 있습니다. 많은 경우. 자, 이것을 말하면서 비동기 및 동기화 기능 모두에서 결과를 수집하는 질문에 대한 범위를 유지하십시오. 감사. – Merc

+0

어떤 기능이 동기인지 알고있는 경우 비동기 기능으로 간단히 감쌀 수 있습니다. 그것은 당신이하려고하는 것보다 쉽습니다. –

답변

1

간단하게 수행 할 수 없습니다. 이야기의 끝.

관련 문제