Skip to content

Instantly share code, notes, and snippets.

@XoseLluis
Created June 25, 2020 20:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save XoseLluis/9b0dff015a079f2235033785bae21cc7 to your computer and use it in GitHub Desktop.
Save XoseLluis/9b0dff015a079f2235033785bae21cc7 to your computer and use it in GitHub Desktop.
Allowing cancellation in an async function
//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