kriskowal/q — pull request #431 by cinderblock (2013-11-08 09:35:05+00:00)
Title: Adding support for NodeJs EventEmitters with Q.ebind()

The current node style wrappers are awesome. However, they don't lend well to _listener_ callbacks used with Node's `EventEmitter` class because they're setup to resolve promises, which can only happen once. Even better is that `EventEmitter`s use separate _listeners_ for all regular, error, and termination events which (usually) have single arguments that don't match the `(err, result)` style callbacks.

`ebind` is intended to fix this discrepancy cleanly and simply and fit inline with the likes of `denodeify` and `nbind`.

That being said, I don't think this should be the final version of this function. It should probably support binding to more than one event at a time. Also, the `'error'` and `'close'` events should be able to be optionally turned on, or redirected to other events as not all `EventEmitter`s implement those events. It could be made way more generic, while mathcing the argument order of `Q.then` and `Q.done`, with something like this:

```
Q.ebind = function (eventEmitter) {
return function (resolvingEvents, rejectingEvents, progressEvents) {
deferred = Q.defer();
for (var i in resolvingEvents)
eventEmitter.on(resolvingEvents[i],deferred.resolve);
...
```
-----

I've only been playing with NodeJS on the side so I hope this is useful. This is intended to be a proof of concept and to make sure the idea is out there. I'm also probably missing runtime checks or even using promises wrong. If there is already another clean way to do this, I'd love to know about it!