Skip to content

AlonMiz/poll-until-promise

Repository files navigation

NPM Version Build

Poll Until Promise

Wait until the executed promise resolved to a true value, Execute it every x milliseconds and stop after y milliseconds.

Install

npm install poll-until-promise

Usage

Fetching data

const { waitFor } = require('poll-until-promise');

waitFor(() => fetch('/get-data'), { interval: 100 })
    // Tries every 100ms (from the last failure)
    .then(value => console.log('Yey', value))
    .catch(err => console.error(err));

Using async

import { waitFor, AbortError } from 'poll-until-promise';

async function waitForDomElement(cssSelector = 'div') {
  try {
    const element = await waitFor(() => {
      const element = window.document.querySelector(cssSelector);
      if (!element) throw new Error(`failed to find element: ${cssSelector}`);
      return element;
    }, { timeout: 60_000 });

    return element;
  } catch (e) {
    console.error('faled to find dom element:', e);
    throw e;
  }
}

async function retryFetch(path = '/get-data') {
  try {
    const data = await waitFor(async () => {
      const res = await fetch(path);

      // Stop immediately if the resource doesn't exist
      if (res.status === 404) {
        throw new AbortError(res.statusText);
      }

      return res.json();
    }, { timeout: 60_000, interval: 1000 });
  } catch (e) {
    console.error('faled to fetch:', e);
    throw e;
  }
}

Waiting for something to be successful

const { waitFor } = require('poll-until-promise');

waitFor(() => {
  if (Math.random() >= 0.5) {
    throw new Error('try again');
  } else {
    console.log('all good')
  }
})
  .then(() => console.log('Yey'))
  .catch(err => console.error(err));

Using the class

const { PollUntil } = require('poll-until-promise');

const later = Date.now() + 1000; // 1 seconds into the future

let pollUntilPromise = new PollUntil();
pollUntilPromise
    .stopAfter(2 * 1000)    // Stop trying after 2 seconds
    .tryEvery(100)          // Tries every 100ms (from the last failure)
    .execute(() => {
        return new Promise((resolve, reject) => {
            if (+Date.now() >= later) {
                return resolve(true); // Some truthy value
            }
            reject(false);
        })
    })
    .then(value => console.log('Yey', value))
    .catch(err => console.error(err));

Options

const options = {
    interval: 100,
    backoffFactor: 1, // Exponential interval increase. Defaults to 1, which means no backoff
    backoffMaxInterval: 250, // Sets a maximum interval when using backoff. Defaults to the timeout value
    timeout: 1000,
    stopOnFailure: false, // Ignores promise rejections
    verbose: false,
    message: 'Waiting for time to pass :)', // custom message to display on failure
    maxAttempts: 5, // maximum attempts to make (default: no limit). Will still fail to wait if reaching timeout before attempts exhausted
};
let pollUntilPromise = new PollUntil(options);

Methods

  • isResolved
pollUntilPromise.isResolved()
  • isWaiting
pollUntilPromise.isWaiting()
  • getPromise
pollUntilPromise.getPromise().then(() => console.log('OMG'))

Static Function

const PollUntil = require('poll-until-promise');
const later = Date.now() + 1000; // 1 seconds into the future

let pollUntilPromise = new PollUntil();
pollUntilPromise
    .stopAfter(2 * 1000)
    .tryEvery(100)
    .execute(() => {
        if (+Date.now() >= later) {
            return true;
        }
        return false;
    })
    .then((value) => console.log('Yey', value))
    .catch((err) => console.error(err));