Skip to content

Instantly share code, notes, and snippets.

@chrisjhoughton
Created December 10, 2013 13:02
Show Gist options
  • Save chrisjhoughton/7890239 to your computer and use it in GitHub Desktop.
Save chrisjhoughton/7890239 to your computer and use it in GitHub Desktop.
Wait for a global variable to exist on the page.
var waitForGlobal = function(key, callback) {
if (window[key]) {
callback();
} else {
setTimeout(function() {
waitForGlobal(key, callback);
}, 100);
}
};
waitForGlobal("jQuery", function() {
console.log("found it");
});
@fawzanm
Copy link

fawzanm commented Mar 25, 2021

Thank you for saving my head.

@tsgrgo
Copy link

tsgrgo commented Dec 22, 2022

I wrote a more generalized function that lets you busy wait for any condition. It returns a promise instead of using a callback.

/**
 * Function to wait for predicates.
 * @param {function() : Promise.<Boolean> | function() : Boolean} predicate
 * - A function that returns or resolves a bool
 * @param {Number} [timeout] - Optional maximum waiting time in ms after rejected
 */
export function waitFor(predicate, timeout) {
    return new Promise((resolve, reject) => {
        let running = true;

        const check = async () => {
            const res = await predicate();
            if (res) return resolve(res);
            if (running) setTimeout(check, 100);
        };

        check();

        if (!timeout) return;
        setTimeout(() => {
            running = false;
            reject();
        }, timeout);
    });
}

Here is an example to check for global properties without timeout:

await waitFor(() => window.hasOwnProperty('propName'));

// Or if propName is not falsey if defined:
await waitFor(() => window.propName);

// You can also assign it to a variable
const propName = await waitFor(() => window.propName);

And if you want timeout:

try {
    await waitFor(() => window.hasOwnProperty('propName'), 2000);
} catch (err) {
    console.error('timed out')
}

@flashlab
Copy link

I wrote a more generalized function that lets you wait for any condition. It returns a promise instead of using a callback.

/**
 * Function to wait for predicates.
 * @param {function() : Boolean} predicate - A function that returns a bool
 * @param {Number} [timeout] - Optional maximum waiting time in ms after rejected
 */
export function waitFor(predicate, timeout) {
  return new Promise((resolve, reject) => {
    const check = () => {
      console.log('checking', predicate());
      if (!predicate()) return;
      clearInterval(interval);
      resolve();
    };
    const interval = setInterval(check, 100);
    check();

    if (!timeout) return;
    setTimeout(() => {
      clearInterval(interval);
      reject();
    }, timeout);
  });
}

Here is an example to check for global properties without timeout:

await waitFor(() => window.hasOwnProperty('propName'));

And if you want timeout:

try {
    await waitFor(() => window.hasOwnProperty('propName'), 2000);
} catch (err) {
    console.error('timed out')
}

If you want to check nested sub keys, something like this might work:

await waitFor(() => window?.MY?.Object?.property?.functionName);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment