等待承诺的事件

时间:2015-04-07 21:01:57

标签: node.js events socket.io promise bluebird

我很想将一个事件包装在一个承诺中。

更具体地说,我喜欢有一种方法来承诺从每个发出的事件中返回值。

var events = require('events')
var eventEmitter = new events.EventEmitter()

eventEmitter.on("add", function(data){
  console.log(data+1)
  return data+1
})

eventEmitter.emit('add', 5)
eventEmitter.emit('add', 3)

setTimeout(function(){
  eventEmitter.emit('add', 13)
}, 1000)

setTimeout(function(){
  eventEmitter.emit('add', 10)
}, 3000)

这是一个会发出6, 4, 14, 11的事件。我喜欢的是一个返回[6, 4, 14, 11]的承诺包装器。

//eventWrapper(emissions, event, [eventArguments])

eventWrapper(4, eventEmitter, "add").then(console.log) // [6, 4, 14, 11]

理想情况下还有超时参数,因此如果排放没有在x秒内返回并满足排放,则会出现错误。

最后(我知道这已经达到了一定程度),但是当涉及到socket.io时,广播的排名.on处理程序无法返回回调的问题,这个非常专业的用途,事件可以代理由一个完全不同的事件处理,像这样。

eventEmitter.on("callback", function(data){
  console.log(data+1)
  return data+1
})

eventEmitter.on("add", function(data){
  eventEmitter.emit("callback", data)
})

我没有看回原始事件的回调,而是需要一种传递第二个事件的方法,并将回调代理到该事件。

理想情况下,该功能看起来像这样。

//eventWrapper(numberOfExpectedReturnedEvents, delimiterTimeoutIntervalBetweenEvents, eventAndParameters, proxyEventAndParameters)
eventWrapper(numberOfSockets, 5000, [socket.on, "action"], [socket.io, "callback"])

1 个答案:

答案 0 :(得分:1)

像Florian所说:承诺不是事件发射器

承诺代表单个值+时间。但是,在您的代码中,您尝试表示多次调用的事件。

如果承诺采用单个值并向其添加时间元素。您正在尝试获取多个值(值的迭代)并为其添加时间。这被称为Observable而不是promise。承诺不是解决问题的好模型。

以下是使用RxJS的示例,因为可观察量不在EcmaScript中(but they're on their way):

var EventEmitter = require('events').EventEmitter;
var emitter = new EventEmitter();

// an observable is what you use for multiple events
// fromEvent is the `promisify` of observables, you can also create them
// from sources - analogous to the promise constructor 
var observable = Rx.Observable.fromEvent(emitter, 'add');

// scanning a value and mappingthe result is done by `.scan`
// note how the syntax is similar to promise
// chaining - observables are functional and chain like promises
// observables also consume promises and can produce promises 
observable = observable.map(function(val){
    return val + 1;
});

// subscribe is like .done
observable.subscribe(console.log);