Last active
March 18, 2020 04:50
-
-
Save mmis1000/821ffb791bd87229bb78e3fc4f1c881d to your computer and use it in GitHub Desktop.
Abortable promise
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import AbortController from "abort-controller" | |
import { AbortSignal } from "abort-controller" | |
import { AbortablePromise } from "." | |
var controller = new AbortController() | |
function sleep (signal: AbortSignal, time: number) { | |
return AbortablePromise(signal, function (resolve, reject, handleCancel) { | |
var id = setTimeout(resolve, time) | |
handleCancel(() => { | |
clearTimeout(id) | |
throw new Error('aborted timeout') | |
}) | |
}) | |
} | |
async function main (signal: AbortSignal) { | |
await sleep(signal, 1000) | |
console.log(1) | |
await sleep(signal, 1000) | |
console.log(2) | |
await sleep(signal, 1000) | |
console.log(3) | |
await sleep(signal, 1000) | |
console.log(4) | |
await sleep(signal, 1000) | |
console.log(5) | |
} | |
main(controller.signal) | |
.then(function () { | |
console.log('resolved') | |
}) | |
.catch(function (err) { | |
console.error(err) | |
}) | |
setTimeout(() => { | |
controller.abort() | |
}, 2500) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import AbortController from "abort-controller" | |
import { AbortSignal } from "abort-controller" | |
class DOMException extends Error { | |
name = 'DOMException' | |
} | |
export function AbortablePromise<T>( | |
signal: AbortSignal, | |
callback: ( | |
resolveFn: (arg: T) => void, | |
rejectFn: (err: any) => void, | |
installCancel: (cancelCb: () => T) => void | |
) => void | |
) { | |
return new Promise<T>((resolve, reject) => { | |
if (signal.aborted) { | |
// ignore it completely | |
return reject(new DOMException('Already aborted signal')) | |
} | |
// throw dom exception by default | |
let cancelHandler: () => T = function () { | |
throw new DOMException('Aborted') | |
} | |
let fulfilled = false | |
function onResolve(res: T) { | |
if (!signal.aborted) { | |
signal.removeEventListener('abort', onAbort) | |
resolve(res) | |
} | |
} | |
function onReject(err: any) { | |
if (!signal.aborted) { | |
signal.removeEventListener('abort', onAbort) | |
reject(err) | |
} | |
} | |
function onAbort() { | |
signal.removeEventListener('abort', onAbort) | |
Promise.resolve().then(cancelHandler).then(resolve, reject) | |
} | |
signal.addEventListener('abort', onAbort) | |
callback(onResolve, onReject, function handleCancel(handler) { | |
cancelHandler = handler | |
}) | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "abortable-promise", | |
"version": "1.0.0", | |
"description": "", | |
"main": "index.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"author": "", | |
"license": "ISC", | |
"dependencies": { | |
"abort-controller": "^3.0.0" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment