Description
What problem are you trying to solve?
(I did originally suggest this on the Observable proposal but it was suggested I propose this here instead.)
AbortSignal teardown is still fairly hazardous when relying on .addEventListener
as the event may have already fired so it's very easy to have cleanup steps that don't occur when they should, the observable proposal adds a .addTeardown
method that calls the given teardown steps immediately if the associated signal is already aborted else adds a listener.
Functionally there's not really any significant reason this method should be exclusive to Observables as the same patterns that have problems can occur when authoring code than involves Promises and/or callbacks.
What solutions exist today?
The alternative is writing a wrapper in userland, however in practice developers tend to forget the synchronously cancelled case which is why the Observable proposal even has the method.
How would you solve it?
I'd like to suggest that the method proposed as part of Observable is added to AbortSignal
proper so that it can be used for all uses not just Observable.
As an example of usage:
function delay(time, { signal }={}) {
return new Promise((resolve) => {
const timeout = setTimeout(resolve, time);
signal?.addTeardown(() => clearTimeout(timeout));
});
}
// Already aborted
const p = delay(1000, { signal: AbortSignal.abort() });
This basically mirrors the comparable usage in Observable:
function interval(time) {
return new Observable(subscriber => {
const interval = setInterval(() => subscriber.next(), time);
// If we added the method to AbortSignal, then this could just be
// subscriber.signal.addTeardown(() => clearInterval(interval)) instead
subscriber.addTeardown(() => clearInterval(interval));
});
}
// Cancels immediately
interval(1000).subscribe({ ... }, { signal: AbortSignal.abort() });
Anything else?
No response