@nesvet/n
Version:
Various utilities
66 lines • 2.31 kB
JavaScript
/**
* Waits until a condition function returns true
* @param condition Function that returns true when the waiting should end
* @param options Configuration options
* @returns Promise resolving to true when condition is met, or false on timeout (if throwOnTimeout is false)
*/
export function waitFor(condition, options = {}) {
const { timeout = 5000, interval = 100, throwOnTimeout = true, timeoutMessage = "Operation timed out", onInterval, onTimeout, onSuccess, immediateFirstCheck = true } = options;
return new Promise((resolve, reject) => {
const startTime = Date.now();
let timeoutId = null;
let isResolved = false;
let isCheckInProgress = false;
const cleanup = () => {
if (timeoutId)
clearTimeout(timeoutId);
isResolved = true;
};
const handleSuccess = () => {
if (isResolved)
return;
cleanup();
onSuccess?.();
resolve(true);
};
const handleTimeout = () => {
if (isResolved)
return;
cleanup();
onTimeout?.();
if (throwOnTimeout)
reject(new Error(timeoutMessage));
else
resolve(false);
};
const checkCondition = async () => {
if (isCheckInProgress || isResolved)
return;
isCheckInProgress = true;
try {
if (await condition())
handleSuccess();
else if (!isResolved) {
onInterval?.(Date.now() - startTime);
setTimeout(checkCondition, interval);
}
}
catch (error) {
if (!isResolved) {
cleanup();
reject(error);
}
}
finally {
isCheckInProgress = false; // eslint-disable-line require-atomic-updates
}
};
if (timeout > 0)
timeoutId = setTimeout(handleTimeout, timeout);
if (immediateFirstCheck)
queueMicrotask(checkCondition);
else
setTimeout(checkCondition, interval);
});
}
//# sourceMappingURL=waitFor.js.map