Skip to content

Instantly share code, notes, and snippets.

@ptts
Created December 8, 2024 13:55
Show Gist options
  • Save ptts/282c8efc042f414fc54e29f3edffbf50 to your computer and use it in GitHub Desktop.
Save ptts/282c8efc042f414fc54e29f3edffbf50 to your computer and use it in GitHub Desktop.
A wrapper around a promise or function to enforce a minimum delay, e.g. for artificial delays in UIs
/**
* Ensures that a promise resolves or rejects after at least a specified delay.
*
* @param promiseOrFn - A promise or a function that returns a promise or value.
* @param delay - Minimum time (in ms) to wait before resolving or rejecting (default: 800ms).
* @param options - Configuration object:
* - delayRejection (default: false): If true, ensures that rejections also respect the minimum delay.
* @returns The resolved value of the provided promise.
* @throws If the provided promise rejects or if `promiseOrFn` is a function that throws.
*/
const DEFAULT_DELAY_MS = 800;
async function withMinDelay<T>(
promiseOrFn: Promise<T> | (() => T | Promise<T>),
delay: number = DEFAULT_DELAY_MS,
{
delayRejection = false,
}: {
delayRejection?: boolean;
} = {}
): Promise<T> {
if (delay < 0) {
throw new Error("Delay must be a non-negative number.");
}
const promise = Promise.resolve().then(() =>
typeof promiseOrFn === "function" ? promiseOrFn() : promiseOrFn
);
const delayPromise = new Promise<void>((resolve) =>
setTimeout(resolve, delay)
);
if (delayRejection) {
return promise.then(
(result) => delayPromise.then(() => result),
(error) => delayPromise.then(() => Promise.reject(error))
);
}
const [result] = await Promise.all([promise, delayPromise]);
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment