ThomasReggi
ThomasReggi

Reputation: 59485

Waiting for events with a promise

I would love to wrap an event in a promise.

More specifically I'd love to have an a way to have a promise that returns the values from every emitted event.

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)

Here's a event that will emit 6, 4, 14, 11. What I'd love is a promise wrapper that returns [6, 4, 14, 11].

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

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

Ideally there's a timeout argument as well so if an emission doesn't return and meet the emissions within x amount of seconds there's an error.

Finally (I know this is reaching a bit), but when it comes to socket.io there's an issue where upon the broadcasted emisson .on handlers won't return a callback, in this very specialized use, the event could be proxied to be handled by a totally different event, like this.

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

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

Instead of watching the original event for the callback, I'd need a way to pass in a second event, and proxy the callback to that event.

Ideally the function looked like this.

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

Upvotes: 3

Views: 1861

Answers (1)

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276496

Like Florian said: A Promise is not an event emitter.

A promise represents a single value + time. However, in your code you're trying to represent an event which gets called multiple times.

If a promise is taking a single value and adding a time element to it. You're trying to take multiple values (an iteration of values) and add time to it. This is called an Observable and not a promise. A promise is not a good model for your problem.

Here is an example using RxJS since observables are not in EcmaScript yet (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);

Upvotes: 1

Related Questions