- From: James Browning <notifications@github.com>
- Date: Sat, 06 Feb 2021 16:51:39 -0800
- To: whatwg/dom <dom@noreply.github.com>
- Cc: Subscribed <subscribed@noreply.github.com>
- Message-ID: <whatwg/dom/issues/946/774568115@github.com>
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