Skip to content

Instantly share code, notes, and snippets.

@albannurkollari
Created October 24, 2023 10:25
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 albannurkollari/1338321380b0f795afd63d0ed56d67ec to your computer and use it in GitHub Desktop.
Save albannurkollari/1338321380b0f795afd63d0ed56d67ec to your computer and use it in GitHub Desktop.
Polls a given callback function until it resolves or the `maxTries` is reached.
/** `⚠️ DevNote`: Should always resolve and never reject. */
type PollRequestCallback = (count: number) => Promise<{ fulfilled: boolean; value: any }>;
type PollRequestOptions = { delay: number | 1000; maxTries: number | 10 };
/**
* Polls a given callback function until it resolves or the `maxTries` is reached.
*
* The resolved value should be an object with `fulfilled` and `value` properties.
* If `fulfilled` is `true`, then it will stop polling at that count and resolve the
* given `value`.
*
* If after all tries are exhausted, it will resolve with `undefined`.
* @template T
* @param {PollRequestCallback} requester
* @param {Partial<PollRequestOptions>} [{ delay = 1000, maxTries = 10 }={}]
* @return {Promise<T | void>}
*/
export const pollRequest = <T>(
requester: PollRequestCallback,
{ delay = 1000, maxTries = 10 }: Partial<PollRequestOptions> = {},
): Promise<T | void> => {
return new Promise<T | void>(async (resolve) => {
for (let tryCount = maxTries; tryCount > 0; tryCount--) {
const { fulfilled, value } = await requester(tryCount);
if (fulfilled) {
resolve(value);
return;
}
if (tryCount > 1) {
await new Promise((innerResolve) => setTimeout(innerResolve, delay));
}
}
resolve();
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment