【问题标题】:Collect results using both async and sync calls使用异步和同步调用收集结果
【发布时间】:2013-10-29 08:24:47
【问题描述】:

我有以下代码。它基本上扩展了 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 );
});

谢谢!

【问题讨论】:

  • 正如链接问题的另一个response 所说,事件处理程序的设计模式为“即发即弃”。整个node.js平台就是这样设计的。
  • 在某些情况下,“一劳永逸”并不是您想要的。很多情况。现在,说了这么多,请保持问题的范围——即从异步和同步函数中收集结果。谢谢。
  • 如果您知道哪些函数是同步的,您可以简单地将它们包装在异步函数中。这可能比您尝试做的更容易。
  • 我对答案很感兴趣,既要改进功能,又要看看是否有可能做这样的事情。是的,包装函数很容易......

标签: node.js asynchronous


【解决方案1】:

这根本做不到。故事结束。

【讨论】:

    猜你喜欢
    • 2016-06-21
    • 2016-05-14
    • 2019-09-30
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多