Created
June 25, 2020 20:23
-
-
Save XoseLluis/9b0dff015a079f2235033785bae21cc7 to your computer and use it in GitHub Desktop.
Allowing cancellation in an async function
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
//helper function to use in the async function containing multiple async calls | |
function checkCancelation(cancelationToken){ | |
if (cancelationToken && cancelationToken.reject){ | |
console.log("throwing"); | |
throw new Error("Rejection forced"); | |
} | |
if (cancelationToken && cancelationToken.cancel){ | |
console.log("cancelling"); | |
//return a Promise that never resolves | |
return new Promise(()=>{}); | |
} | |
return false; | |
} | |
//sample async functions | |
function getLastMessageId(){ | |
return new Promise(res => { | |
setTimeout(() => res(111), 1500); | |
}); | |
} | |
function getMessageText(id){ | |
return new Promise(res => { | |
setTimeout(() => res("this is the last message"), 1500); | |
}); | |
} | |
function formatText(txt){ | |
let formattedTxt = `[[${txt}]]`; | |
return new Promise(res => { | |
setTimeout(() => res(formattedTxt), 1500); | |
}); | |
} | |
//async function allowing cancellation | |
async function getLastMessageFormatted(cancelationToken){ | |
let id = await (checkCancelation(cancelationToken) | |
|| getLastMessageId()); | |
console.log("ID obtained"); | |
let txt = await (checkCancelation(cancelationToken) | |
|| getMessageText(id)); | |
console.log("Message obtained"); | |
let msg = await (checkCancelation(cancelationToken) | |
|| formatText(txt)); | |
console.log("Message formatted"); | |
return msg; | |
} | |
//async main | |
(async () => { | |
console.log("-- test 1"); | |
let msg = await getLastMessageFormatted(); | |
console.log("message: " + msg); | |
console.log("-- test 2"); | |
let cancellationToken = {}; | |
//reject after 1 second | |
setTimeout(() => cancellationToken.reject = true, 1000); | |
try{ | |
msg = await getLastMessageFormatted(cancellationToken); | |
console.log("message: " + msg); | |
} | |
catch (ex){ | |
console.error("Exception: " + ex.message); | |
} | |
console.log("-- test 3"); | |
cancellationToken = {}; | |
//cancel after 1 second | |
setTimeout(() => cancellationToken.cancel = true, 1000); | |
//when cancelling we return a simple Promise, that won't keep the program running | |
//(it's real IO-timeout calls, not the Promise itself, what keeps the node.js loop running) | |
//If I just want to keep it running longer, just use this keep alive timeout | |
setTimeout(() => console.log("keep alive finished"), 10000); | |
try{ | |
msg = await getLastMessageFormatted(cancellationToken); | |
console.log("message: " + msg); | |
} | |
catch (ex){ | |
console.error("Exception: " + ex.message); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment