Reputation: 953
i have created this class to check if the function has been loaded. It works fine, except that I want to avoid using eval to evaluate the function name from a variable. I appreciate any help with this. Thanks.
class scriptLoader {
constructor(fn, max_try) {
this.fn = fn; //the func name being passed as a string
this.count = 0; //init count start value
this.max_try = max_try; //the max times to try
}
waitForScriptToLoad() {
'use strict';
let my_function = eval(this.fn); //this evaluate the string, i.e 'myfunc' to myfunc()
if(typeof my_function === "function") {
my_function();
} else {
if(this.count<this.max_try) {
var that = this;
setTimeout(function() {that.count++; that.waitForScriptToLoad();},100); //wait 100ms and try again
} else {
return false;
}
}
}
}
I instantiate the class like so:
loadData = new scriptLoader('Worker.fetch_form_data', 3);
loadData.waitForScriptToLoad();
Upvotes: 0
Views: 51
Reputation: 370729
Assuming that the script you're trying to detect will be located on the global object, split the string by .
s and check to see if the nested property exists on the global object:
class scriptLoader {
constructor(propsStr, max_try) {
this.propsStr = propsStr; //the func name being passed as a string
this.count = 0; //init count start value
this.max_try = max_try; //the max times to try
}
waitForScriptToLoad() {
'use strict';
const possibleFn = this.propsStr.split('.').reduce((a, prop) => (a?.[prop]), globalThis);
if (typeof possibleFn === "function") {
possibleFn();
} else {
if (this.count < this.max_try) {
console.log('retrying');
setTimeout(() => {
this.count++;
this.waitForScriptToLoad();
}, 100); //wait 100ms and try again
}
}
}
}
// Dynamic loading of script:
setTimeout(() => {
window.obj = {};
}, 50);
setTimeout(() => {
window.obj.nested = {
fn: () => console.log('fn')
};
}, 150);
const loadData = new scriptLoader('obj.nested.fn', 3);
loadData.waitForScriptToLoad();
Also note:
const
rather than let
if you don't require reassignment - avoid var
that = this
antipatternloadData
is implicitly global since you didn't declare it (consider enabling strict mode at the top level)Upvotes: 1