Created
December 10, 2013 13:02
-
-
Save chrisjhoughton/7890239 to your computer and use it in GitHub Desktop.
Wait for a global variable to exist on the page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var waitForGlobal = function(key, callback) { | |
if (window[key]) { | |
callback(); | |
} else { | |
setTimeout(function() { | |
waitForGlobal(key, callback); | |
}, 100); | |
} | |
}; | |
waitForGlobal("jQuery", function() { | |
console.log("found it"); | |
}); |
Here another version for nested sub keys:
window.checkNested = function(obj, args) {
for (var i = 0; i < args.length; i++) {
if (!obj || !obj.hasOwnProperty(args[i])) {
return false;
}
obj = obj[args[i]];
}
return true;
}
window.waitForGlobal = function(keyPath, callback) {
var args = keyPath.split('.');
if (window.checkNested(window, args)) {
callback();
} else {
setTimeout(function() {
window.waitForGlobal(keyPath, callback);
}, 100);
}
}
Usage:
window.waitForGlobal("MY.fn", function() {
console.debug("MY.fn is defined: ", window.MY.fn);
});
Note: The keyPath can also contain more subkeys, e.g. MY.Object.property.functionName
or none child property: jQuery
Thank you for saving my head.
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')
}
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
Here's support for sub-keys on window, eg:
window.MY.fn