Created
April 29, 2020 11:57
-
-
Save tomsaleeba/79384652da2515607bec74e2f45b7e38 to your computer and use it in GitHub Desktop.
A test to see if you can truly cancel JS promises. Spoiler: you can't.
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
// Question: does calling reject on a running promise cut it short? | |
// Answer: sort of. It returns to the caller early but it keep running behind | |
// the scenes. So more of a short-circuit than really being cancelled. | |
const printFrequency = 500 | |
const printRounds = 10 | |
const cancelPoint = 7 | |
let someOtherState = 'untouched' | |
const { thePromise, cancel } = (function slowCancellablePromise() { | |
let cancel | |
const thePromise = new Promise((resolve, reject) => { | |
cancel = () => { | |
reject('cancelled') | |
} | |
let count = 1 | |
function printAndWait() { | |
console.log('hello ' + count) | |
someOtherState = count | |
setTimeout(() => { | |
if (count++ >= printRounds) { | |
return resolve() | |
} | |
printAndWait() | |
}, printFrequency) | |
} | |
printAndWait() | |
}) | |
return { thePromise, cancel } | |
})() | |
thePromise | |
.then(() => console.log('finished normally')) | |
.catch(err => console.error('finished with error: ' + err)) | |
.finally(() => { | |
console.log( | |
`after promise has returned, someOtherState = ${someOtherState}`, | |
) | |
console.log('waiting until the promise has actually finished...') | |
setTimeout(() => { | |
console.log( | |
`after promise has actually finished, someOtherState = ${someOtherState}`, | |
) | |
}, printFrequency * (printRounds - cancelPoint)) | |
}) | |
console.log('waiting for a bit...') | |
setTimeout(() => { | |
console.log('cancelling promise') | |
cancel() | |
console.log('the promise should stop printing') | |
}, printFrequency * cancelPoint) | |
// the output: | |
// hello 1 | |
// waiting for a bit... | |
// hello 2 | |
// hello 3 | |
// hello 4 | |
// hello 5 | |
// hello 6 | |
// hello 7 | |
// cancelling promise | |
// the promise should stop printing | |
// finished with error: cancelled | |
// after promise has returned, someOtherState = 7 | |
// waiting until the promise has actually finished... | |
// hello 8 | |
// hello 9 | |
// hello 10 | |
// after promise has actually finished, someOtherState = 10 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment