Re: [whatwg/dom] Expose an `aborted` promise on AbortSignal? (#946)

I've been doing a similar thing since Node got support for `AbortSignal`, basically a wrapper that calls a function with a linked abort signal that gets disconnected once the promise returned from the function resolves:

```ts
// doAbortable.ts
export default async function doAbortable<R>(
    signal: AbortSignal | undefined,
    func: (abortSignal: AbortSignal) => R | Promise<R>,
): Promise<R> {
    const innerController = new AbortController();
    const abortInner = () => innerController.abort();
    if (signal?.aborted) {
        throw new AbortError();
    } else {
        signal?.addEventListener("abort", abortInner, { once: true });
    }
    try {
        return await func(controller.signal);
    } finally {
        // this allows innerController to be garbage collected
        // and hence if nothing is holding a strong reference to the signal
        // that too may be collected
        signal?.removeEventListener("abort", abortInner);
    }
}
```

```ts
export default function animationFrame(abortSignal) {
    // the inner abortSignal can be garbage collected
    // once the promise returned resolves as there'll be
    // no references to it remaining once doAbortable
    // calls removeEventListener("abort", abortInner);
    return doAbortable(abortSignal, (abortSignal) => {
        return new Promise((resolve, reject) => {
            const frameRequest = requestAnimationFrame(time => resolve(time));
            abortSignal.addEventListener("abort", () => cancelAnimationFrame(frameRequest));
        });
    });
}
```

I've found it works fairly cleanly, although the extra wrapper is slightly annoying. This might be able to improved if [function](https://github.com/tc39/proposal-decorators/blob/master/EXTENSIONS.md#function-decorators-and-annotations) and [parameter](https://github.com/tc39/proposal-decorators/blob/master/EXTENSIONS.md#parameter-decorators-and-annotations) become a thing cause then I could just annotate the abort param and decorate it e.g:

```js
@abortable
export default function delay(time, @abortable.signal abortSignal) {
  // ... create delay promise
}
```

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

Received on Sunday, 7 February 2021 00:51:51 UTC