Skip to content

Instantly share code, notes, and snippets.

@Ctrlmonster
Created January 6, 2023 18:45
Show Gist options
  • Save Ctrlmonster/f8adf049758de21dede6ecae4dfd47a5 to your computer and use it in GitHub Desktop.
Save Ctrlmonster/f8adf049758de21dede6ecae4dfd47a5 to your computer and use it in GitHub Desktop.
small helper function to promisify via callbacks
export type Work = (...args: any[]) => any;
// Pass a function that provides a callback as single argument and returns another function F that calls that
// callback at some point. The result of makeContinuable will be a function that returns a promise that will
// resolve to the return value of F, once the callback is called.
export function makeContinuable<F extends Work>(wrapperFn: (cb: () => void) => F) {
return async (...args: Parameters<F>) => {
const outerPromise = new Promise<ReturnType<F>>(async (resolve1) => {
let res = null as ReturnType<F>;
// create another promise in whose executioner we'll call the passed function
const innerPromise = new Promise<void>((resolve2) => {
const innerFn = wrapperFn(resolve2);
res = innerFn(...args);
});
// await that promise and then resolve the outer promise with the result of the inner function
await innerPromise;
resolve1(res);
});
return await outerPromise;
}
}
// =====================================================================================================================
// Example:
const step1 = makeContinuable((cb) => (a: number, b: number) => {
// do some stuff that takes a while (play an animation, wait for a user input, etc.)
setTimeout(cb, 2000); // then call the callback
return a + b;
});
const step2 = makeContinuable((cb) => (a: number, b: number) => {
// do more stuff that takes time
setTimeout(cb, 2000);
return a - b;
});
// example event consisting of multiple steps (e.g. wait for user selection, play some animation, show some result)
const myEvent = makeContinuable((cb) => async () => {
const a = await step1(1, 2);
const b = await step2(3, 4);
cb();
return a + b;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment