Skip to content

Instantly share code, notes, and snippets.

@MattiasBuelens
Created September 12, 2019 18:18
Show Gist options
  • Save MattiasBuelens/94a34b8349e1597b86f50d6e6e3c4424 to your computer and use it in GitHub Desktop.
Save MattiasBuelens/94a34b8349e1597b86f50d6e6e3c4424 to your computer and use it in GitHub Desktop.
raceAbort example
function delay(): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, 100));
}
function abortableDelay(signal: AbortSignal): Promise<void> {
return new Promise((resolve, reject) => {
if (signal.aborted) {
return reject(new DOMException('Aborted', 'AbortError'));
}
const onAbort = () => {
clearTimeout(timeout);
signal.removeEventListener('abort', onAbort);
reject(new DOMException('Aborted', 'AbortError'));
};
const timeout = setTimeout(() => {
signal.removeEventListener('abort', onAbort);
resolve();
}, 100);
});
}
async function doSomething(signal: AbortSignal) {
// No way to abort this long-running task,
// so we always have to wait for it to complete... :-(
await delay();
// Better: stop waiting as soon as the signal becomes aborted
await raceAbort(delay(), signal);
// Even better: make the task handle aborting
await abortableDelay(signal);
}
const controller = new AbortController();
setTimeout(() => controller.abort(), 1000); // try changing this delay
doSomething(controller.signal)
.then(() => console.log('done'))
.catch((reason) => console.error(reason));
function raceAbort<T>(promise: Promise<T>, signal: AbortSignal): Promise<T> {
return new Promise<T>((resolve, reject) => {
if (signal.aborted) {
promise.catch(() => {}); // ignore unhandled rejections
return reject(new DOMException('Aborted', 'AbortError'));
}
const onAbort = () => {
signal.removeEventListener('abort', onAbort);
reject(new DOMException('Aborted', 'AbortError'));
};
signal.addEventListener('abort', onAbort);
promise.then((value) => {
signal.removeEventListener('abort', onAbort);
resolve(value);
}, (reason) => {
signal.removeEventListener('abort', onAbort);
reject(reason);
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment