Closed saschanaz closed 2 months ago
Oh, I filed #66 and wrote #67 (which removes once: true
from the event listener options that we use) before seeing this by the way. We could keep once
in the event listener options, although it seems like your desire is not to use that directly, but instead introduce an operator that more-or-less gives you a Promise for a single Observable event, right? We've discussed adding .toPromise()
recently (in contrast with toArray()
), which I think offers some pretty explicit language, but also we have .first()
currently commented-out in our WebIDL sketch, which I think satisfies this but with less explicit language. How do any of those sound?
My thought is that the .on()
method would always create an Observable (over the "add event listener" internals) whose teardown is to remove the event listener. Something like toPromise()
or first()
would subscribe to the observable, and unsubscribe after the first event (thus removing the event listener like once: true
would). Maybe we could just uncomment first()
or rename it to toPromise()
or takeImmediately()
? I might prefer toPromise()
to be extra explicit about the scheduling impact.
One problem with a promise returning API is that you'll have an event in a different async context, where e.preventDefault()
is too late.
This can be done like so:
await element.on('click').take(1).forEach(e => {
// Do what you need do with the even in here.
// Since this is synchronously dispatched, things like
// e.preventDefault() can still be used.
});
At this point we've decided to add the first()
Promise-returning operator (see https://github.com/WICG/observable/pull/131 and https://github.com/WICG/observable/issues/126) which I think satisfies this request, and @benlesh has kindly provided a nice example to keep synchronous scheduling when needing synchronously react to the "first" event (in order to preventDefault()
or something like that).
I'll set up https://github.com/WICG/observable/pull/131 to close this issue once merged.
I think this proposal is mostly for repeated events, but is there corresponding way of
once: true
inaddEventListener
?Something like: