-
Notifications
You must be signed in to change notification settings - Fork 319
Add abortSignal.addAbortCallback #1425
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
base: main
Are you sure you want to change the base?
Conversation
|
With regards to the example, the way a user is actually likely to run into this is more like import { operation } from 'some-framework';
async function whatever(signal) {
await Promise.all([
builtin1({ signal }),
operation({ signal }),
builtin2({ signal }),
]);
}From the user's perspective, it is very strange if these are aborted in anything other than LIFO or FIFO order. Users are not (and should not be) reasoning about whether the operations they're calling are defined in their framework or in the platform, and there is no way to understand the |
|
That example is pretty compelling. |
|
I'd like the design to allow #1389 in the future 👀 (doesn't seem to block it right now, which is cool) |
|
From a language-level perspective, I think it's better if we defined the mechanism as a cancelation/abort protocol in the language... of which Specifically, I've been imagining something along the lines of... const genericAbortSignal = {
[Symbol.onabort]() {
// Register and return the abort handle
return {
cancel() { /* Unregister the abort handler */ },
[Symbol.dispose]() { this.cancel(); }
};
},
};
doSomething(genericAbortSignal);
async function doSomething(signal) {
using abortHandle = signal[Symbol.onabort]();
abortHandle.onabort = (reason) => { /* ... */ };
// Do async stuff that can be aborted...
}Then, the actual This type of approach would allow any object to become an AbortSignal. It would allow TC39 to define abort semantic without relying on The requirement of the protocol would be that a call to
class AbortSignal extends EventTarget {
// ...
[Symbol.onabort]() {
let callback;
const self = this;
const handler = {
cancel() {
self.removeEventListener('abort', callback);
};
};
callback = (event) => handler.onabort?.(event.reason);
this.addEventListener('abort', callback, { once: true });
return handler;
}
} |
|
@jasnell There's no need to define a symbol-based protocol. The protocol for consumers can literally be "call (Though I agree that a Edit: also, your implementation ends up still using the |
Only within a hypothetical impl of the abort protocol in the existing I think the nice thing about protocol approach is that it would not require use of the |
|
Calling The main reasons to use a symbol-based rather than string-based protocol are when this is a protocol that arbitrary objects might implement (like Iterator), or when you want to switch on the presence of the protocol (like Promise). Neither holds here. |
|
Symbol vs Not-a-symbol isn't that important to me. I'm good with either. More focused on the overall pattern than the particular color of the bikeshed ;-) |
|
So the only difference between what you're proposing and what's in this PR already is just that instead of the new method returning |
|
That and we'd be sure to define it (in the language) as a protocol that is not dependent specifically on using that is, I want us to say, "An abort signal is any object that implements [...] function" ... as opposed to "An abort signal is always an |
|
Yes, the idea is that ECMAScript would literally use the new method added in this PR (i.e., it will just attempt to call If ECMAScript was going to reach into the internals of AbortSignal there would be no need for the new method. |
| <li> | ||
| <p>[=AbortSignal/Add|Add the following abort steps=] to [=this=]:</p> | ||
| <ol> | ||
| <li><p><a spec=webidl>invoke</a> <var>callback</var> with « », and "<code>report</code>". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noob question: is it implicit that the callback is no longer held once it's called?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The abort algorithms list is cleared when abort signals are run.
This PR is a discussion starter. The goals:
AbortControllerandAbortSignalwithout requiringEventandEventTarget.The behaviour in this PR means that abort reactions in userland and the web platform interleave. @bakkot is keen on this. I'm a little unsure, so I'm interested in more opinions.
I'm a little worried about:
But maybe this already happens with promises?
(See WHATWG Working Mode: Changes for more details.)
Preview | Diff