Skip to content

Instantly share code, notes, and snippets.

@rctay
Last active July 14, 2022 04:44
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 rctay/3a341fad721ee9b54c040a65f252bd18 to your computer and use it in GitHub Desktop.
Save rctay/3a341fad721ee9b54c040a65f252bd18 to your computer and use it in GitHub Desktop.
calling a promise in "fire-and-forget" fashion but surprisingly subsequent code wasn't called
// assume just this and you don't have access to its source code
let doAsyncThing: () => Promise<void>;
// another async fn - eg. logging, GA reporting
const doAsyncThingSafe = (): Promise<void> =>
new Promise((resolve, _reject) => {
console.log('๐ŸŽ‰did <this> where <this = always needs to be done>๐Ÿš€');
resolve();
});
let unfriendlyOneWhoseSignatureDoesNotIndicateIFiredAndForgotAPromise = () => {
doAsyncThing();
};
let iCalledAndIRegrettedIt: () => Promise<void> = async () => {
unfriendlyOneWhoseSignatureDoesNotIndicateIFiredAndForgotAPromise();
await doAsyncThingSafe();
};
let friendlyOneWhoseSignatureIndicatesIFiredAndForgotAPromise = async () => {
void doAsyncThing();
};
let iCalledAndIWasOk: () => Promise<void> = async () => {
friendlyOneWhoseSignatureIndicatesIFiredAndForgotAPromise();
await doAsyncThingSafe();
};
const main = async () => {
doAsyncThing = doAsyncThingImpl1;
try {
console.log('running iCalledAndIRegrettedIt()');
await iCalledAndIRegrettedIt();
} catch (err) {
} finally {
console.log('done with iCalledAndIRegrettedIt()');
}
try {
console.log('running iCalledAndIWasOk()');
await iCalledAndIWasOk();
} catch (err) {
} finally {
console.log('done with iCalledAndIWasOk()');
}
// "running iCalledAndIRegrettedIt()"
// "done with iCalledAndIRegrettedIt()" <--- <this> wasn't done ๐Ÿ˜ข
// "running iCalledAndIWasOk()"
// "๐ŸŽ‰did <this> where <this = always needs to be done>๐Ÿš€"
// "done with iCalledAndIWasOk()"
};
const doAsyncThingImpl1 = (): Promise<void> => {
// to stand-in for analytics().logEvent() that was implemented in Java native code
throw new Error('I interrupted your flow!');
};
main();
// assume just this and you don't have access to its source code
let doAsyncThing: () => Promise<void>;
// another async fn - eg. logging, GA reporting
const doAsyncThingSafe = (): Promise<void> =>
new Promise((resolve, _reject) => {
console.log('๐ŸŽ‰did <this> where <this = always needs to be done>๐Ÿš€');
resolve();
});
let unfriendlyOneWhoseSignatureDoesNotIndicateIFiredAndForgotAPromise = () => {
doAsyncThing();
};
let iCalledAndIRegrettedIt: () => Promise<void> = async () => {
unfriendlyOneWhoseSignatureDoesNotIndicateIFiredAndForgotAPromise();
await doAsyncThingSafe();
};
let friendlyOneWhoseSignatureIndicatesIFiredAndForgotAPromise = async () => {
void doAsyncThing();
};
let iCalledAndIWasOk: () => Promise<void> = async () => {
friendlyOneWhoseSignatureIndicatesIFiredAndForgotAPromise();
await doAsyncThingSafe();
};
const main = async () => {
doAsyncThing = doAsyncThingImpl2;
try {
console.log('running iCalledAndIRegrettedIt()');
await iCalledAndIRegrettedIt();
} catch (err) {
} finally {
console.log('done with iCalledAndIRegrettedIt()');
}
try {
console.log('running iCalledAndIWasOk()');
await iCalledAndIWasOk();
} catch (err) {
} finally {
console.log('done with iCalledAndIWasOk()');
}
// "running iCalledAndIRegrettedIt()"
// "๐ŸŽ‰did <this> where <this = always needs to be done>๐Ÿš€"
// "done with iCalledAndIRegrettedIt()"
// "running iCalledAndIWasOk()"
// "๐ŸŽ‰did <this> where <this = always needs to be done>๐Ÿš€"
// "done with iCalledAndIWasOk()"
};
const doAsyncThingImpl2 = async (): Promise<void> => {
// ^^^^^ added this
// demonstrates that async keyword transforms to Promise reject
throw new Error('I interrupted your flow! 2');
};
const doAsyncThingImpl1 = (): Promise<void> => {
// to stand-in for analytics().logEvent() that was implemented in Java native code
throw new Error('I interrupted your flow!');
};
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment