34 lines
1.1 KiB
JavaScript
34 lines
1.1 KiB
JavaScript
async function defaultWait(ms) {
|
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
}
|
|
|
|
async function waitForCondition(condition, options = {}) {
|
|
const description = options.description || 'condition';
|
|
const timeoutMs = Number.isFinite(options.timeoutMs) ? options.timeoutMs : 5000;
|
|
const intervalMs = Number.isFinite(options.intervalMs) ? options.intervalMs : 250;
|
|
const now = typeof options.now === 'function' ? options.now : () => Date.now();
|
|
const wait = typeof options.wait === 'function' ? options.wait : defaultWait;
|
|
const startedAt = now();
|
|
let lastError = null;
|
|
|
|
while (now() - startedAt <= timeoutMs) {
|
|
try {
|
|
const result = await condition();
|
|
if (result) return result;
|
|
} catch (error) {
|
|
lastError = error;
|
|
}
|
|
|
|
const elapsed = now() - startedAt;
|
|
if (elapsed >= timeoutMs) break;
|
|
await wait(Math.min(intervalMs, Math.max(0, timeoutMs - elapsed)));
|
|
}
|
|
|
|
const suffix = lastError && lastError.message ? `: ${lastError.message}` : '';
|
|
throw new Error(`Timed out waiting for ${description} after ${timeoutMs}ms${suffix}`);
|
|
}
|
|
|
|
module.exports = {
|
|
waitForCondition,
|
|
};
|