[whatwg/dom] Add a method like .addTeardown to AbortSignal (Issue #1289)

### What problem are you trying to solve?

(I did originally suggest this on the [Observable proposal](https://github.com/WICG/observable/issues/146) 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 dangling , the observable proposal adds a [`.addTeardown` method](https://github.com/WICG/observable?tab=readme-ov-file#teardown) that calls the given teardown steps if the associated signal is already aborted.

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 people tend to forget this which is precisely why the Observable proposal even includes 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:

```js
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:

```js
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
internal.subscribe({ ... }, { signal: AbortSignal.abort() });
```

### Anything else?

_No response_

-- 
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/issues/1289
You are receiving this because you are subscribed to this thread.

Message ID: <whatwg/dom/issues/1289@github.com>

Received on Saturday, 18 May 2024 11:43:56 UTC