Skip to content

Instantly share code, notes, and snippets.

@reidev275
Created May 26, 2020 22:37
Show Gist options
  • Save reidev275/043b4be76a3ec12a6cab1ecb9b1cb48b to your computer and use it in GitHub Desktop.
Save reidev275/043b4be76a3ec12a6cab1ecb9b1cb48b to your computer and use it in GitHub Desktop.
import { retryWithDelay } from "solemnlySwear"
// a promise returning function that succeeds apprx 1 in 10 times
const fakePromise = () => {
const randInt = (min: number, max: number): number =>
Math.floor(Math.random() * (max - min + 1)) + min;
const x = randInt(1, 10);
return new Promise((res, rej) => {
if (x === 1) {
res("Success");
} else {
rej("Not your day");
}
});
};
retryWithDelay(fakePromise)()
.catch(console.error)
.then(console.log)
// an alias for our primary type. Functions that return a promise of some type
type Thunk<A> = () => Promise<A>;
// a way to retry a thunk a maximum number of times
export const retry = (times: number) => <A>(thunk: Thunk<A>): Thunk<A> => () =>
thunk().catch((e) => {
console.log("Retrying");
return times === 1 ? e : retry(times - 1)(thunk)();
});
// a simple wrapper around a set timeout to delay execution
const _wait = (ms: number) =>
new Promise((res) => {
setTimeout(() => res(), ms);
});
// a way to delay retry execution
export const delay = (ms: number) => <A>(thunk: Thunk<A>): Thunk<A> => () =>
thunk().catch(() => {
console.log("waiting...");
return _wait(ms).then(thunk);
});
// currently combining them is quite ugly and we'd probably want to do that in the lib if this were the only way
export const retryWithDelay1 = (times: number, msdelay: number) => <A>(
thunk: Thunk<A>
) => retry(times)(delay(msdelay)(thunk))
// However, once we realize all isomorphic functions are monoids we can write
// this append function which combines 0 to infinite instructions into a single instruction.
// The spread operator allows us to omit the brackets in calling code.
type Iso<A> = (a: A) => A;
export const append = <A>(...isos: Iso<A>[]): Iso<A> =>
isos.reduce(
(a: Iso<A>, b: Iso<A>): Iso<A> => (x) => b(a(x)), //append
(x) => x //empty
);
// now that we have a way to easily compose Thunk functions, it may not even make sense to include this helper
export const retryWithDelay = (times: number, ms: number) => append(delay(ms), retry(times))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment