JavaScript waitFor Polling

By  on  

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 awaiting 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!

Recent Features

  • By
    Conquering Impostor Syndrome

    Two years ago I documented my struggles with Imposter Syndrome and the response was immense.  I received messages of support and commiseration from new web developers, veteran engineers, and even persons of all experience levels in other professions.  I've even caught myself reading the post...

  • By
    Camera and Video Control with HTML5

    Client-side APIs on mobile and desktop devices are quickly providing the same APIs.  Of course our mobile devices got access to some of these APIs first, but those APIs are slowly making their way to the desktop.  One of those APIs is the getUserMedia API...

Incredible Demos

  • By
    jQuery Random Link Color Animations

    We all know that we can set a link's :hover color, but what if we want to add a bit more dynamism and flair? jQuery allows you to not only animate to a specified color, but also allows you to animate to a random color. The...

  • By
    Style Textarea Resizers

    Modern browsers are nice in that they allow you to style some odd properties.  Heck, one of the most popular posts on this blog is HTML5 Placeholder Styling with CSS, a tiny but useful task.  Did you know you can also restyle the textarea resizer in WebKit...

Discussion

  1. Who knew asynchronous programming could be this elegant? This waitFor tutorial is a game-changer for smoother code execution. Thanks for sharing, David Walsh!

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!