-
Notifications
You must be signed in to change notification settings - Fork 30.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Promisified equivalent of EventEmitter.once() #20893
Comments
If we decide it's a good idea I'm willing to go ahead and make a PR, I have a branch with this sitting anyway. |
It's basically:
|
@benjamingr That's great, though your implementation does not take care of rejecting the Promise when the error event is fired. Also I wonder if it's not error prone that '.once' have such different return types depending on the second argument. Might be interesting to consider using a different method name. |
I don't think we should do that since event emitters are very general and also because when there is no
I did but it turns out this is backwards compatible because the current behavior for the second argument is to throw a |
This commit introduces a `once` overload which returns a promise if a listener isn't passed to `once`. Fixes: nodejs#20893 PR-URL: Reviewed-By:
I've made a PR @kirly-af to get the discussion going. |
A |
Hey @DaAitch thanks for weighing in, would you mind taking a look at my post here #20909 (comment) and the discussion there with interesting points from several collaborators? I'm wondering if that would make my motivation for considering this clear. Also - how do you think we can have a better |
This should work: const EventEmitter = require('events');
const myEmitter = new EventEmitter();
EventEmitter.prototype.await = function(resolveEvent, rejectEvent) {
var _resolve,
_reject;
var promise = new Promise( (resolve, reject) => {
_resolve = resolve;
this.on(resolveEvent, resolve);
if (rejectEvent) {
_reject = reject;
this.on(rejectEvent, reject);
}
});
return rejectEvent ? promise.finally( () => {
this.off(resolveEvent, _resolve);
this.off(rejectEvent, _reject);
}): promise.finally(() => {
this.off(resolveEvent, _resolve);
});
}
myEmitter.await('ready')
.then(() => console.log('ready1'));
myEmitter.emit('ready'); // 'ready1'
myEmitter.await('ready', 'abort')
.then(() => {console.log('ready2')}, () => {console.log("aborted2")});
myEmitter.emit('ready'); // 'ready2'
myEmitter.emit('abort'); // nothing
myEmitter.await('ready', 'abort')
.then(() => {console.log('ready3')}, () => {console.log("aborted3")});
myEmitter.emit('abort'); // aborted3 |
I believe this can be closed by #26078. |
Hi,
Right now we can subscribe to one time events using
.once()
. Because most (all?) Node event emitters emit an "error" event when an error occurs, it seems reasonable to wrap such events in a Promise. For example:The name
oncePromise
is probably not the best but you get the idea.Given the following implementation:
That way we could leverage async/await flow and error handling:
Existing solutions:
The text was updated successfully, but these errors were encountered: