As more of the JavaScript developers write becomes asynchronous, it’s only natural to need to wait for conditions to be met. This is especially true in a world with asynchronous testing of conditions which don’t provide an explicit await
. I’ve written about waitForever
, waitForTime
, and JavaScript Polling in the past, but I wanted to have a more modern way of await
ing a given state. Let’s have a look at this super useful waitFor
function!
waitFor
is an async
function that allows developers to provide a condition function, polling interval (in milliseconds), and optional timeout (in milliseconds).
// Polls every 50 milliseconds for a given condition
const waitFor = async (condition, pollInterval = 50, timeoutAfter) => {
// Track the start time for timeout purposes
const startTime = Date.now();
while (true) {
// Check for timeout, bail if too much time passed
if(typeof(timeoutAfter) === 'number' && Date.now() > startTime + timeoutAfter) {
throw 'Condition not met before timeout';
}
// Check for conditon immediately
const result = await condition();
// If the condition is met...
if(result) {
// Return the result....
return result;
}
// Otherwise wait and check after pollInterval
await new Promise(r => setTimeout(r, pollInterval));
}
};
Using this function is as simple as just providing a condition function:
await waitFor(() => document.body.classList.has('loaded'));
Timing out the interval and timeout is also simple:
await waitFor(
() => document.body.classList.has('loaded'),
// Checks every 100 milliseconds
100,
// Throws if the "loaded" class isn't on the body after 1 second
10000
);
In an ideal world, developers would always have a handle on the Promise
that could be await
‘d or then
‘d. In practice, however, that isn’t always the case, especially in a testing environment. Being able to await a condition in any environment is an absolute must, so keep this snippet in your toolbox!
The post JavaScript waitFor Polling appeared first on David Walsh Blog.