Reputation: 151
I have found this excellent snippet Make my userscript wait for other scripts to load that shows me how to wait for a function to be available before calling it.
Currently I have this local code in my script which I have put together which works for me
waitForFnc();
function waitForFnc() {
if (typeof Portal.Management_Init == "undefined") {
window.setTimeout(waitForFnc, 50);
}
else {
Portal.Management_Init();
}
}
However, I would like to write a generic version of 'waitForFnc' as I need to do the same thing in several places. Something like
waitForFnc(Portal.Management_Init);
function waitForFnc(fnc) {
if (typeof fnc == "undefined") {
window.setTimeout(waitForFnc(fnc), 50);
}
else {
fnc();
}
}
where I pass the name of the function in which is called when it becomes available. The above code does not work but I am unsure as to how to resolve it.
Regards Paul
Upvotes: 5
Views: 1996
Reputation: 14633
Depending on what you're loading, you might be able to leverage require.js to take care of this for you; that's basically what it's for: http://requirejs.org/docs/why.html#9
Upvotes: 0
Reputation: 2964
There are some potential problems with what you are trying to do. If you call waitForFnc() before Portal is even defined, you will get a null property access exception. If you are trying for a truly generic solution, you will probably have to use eval() *gasp*
While we're at it, let's add support for passing arguments to the function we're waiting on.
function waitForFn(fnName, args){
var fn;
try{
eval("fn = " + fnName);
if(fn){
fn.apply(null, args);
}else{
setTimeout(function(){waitForFn(fnName, args);}, 50);
}
}catch(e){
setTimeout(function(){waitForFn(fnName, args);}, 50);
}
}
waitForFn("Portal.Management_Init", [arg0, arg1]);
Upvotes: 5
Reputation: 340983
In your code replace:
window.setTimeout(waitForFnc(fnc), 50);
with closure:
window.setTimeout(function() {waitForFnc(fnc)}, 50);
But may I ask why do you need such a weird code? I would rather expect to have an API allowing to register some callback:
Portal.onManagementInitAvailable(fn);
Upvotes: 0
Reputation: 26142
Basically, when this line of code is executed: window.setTimeout(waitForFnc(fnc), 50);
, the "waitForFnc" is evaluated before the timeout is set. While you need to pass the calling statement as a parameter.
Here's how you do that:
window.setTimeout(function() {waitForFnc(fnc);}, 50);
What this does, it defines a function, the same way as if you'd write it into the variable:
var myFunc = function() {
waitForFnc(fnc);
};
This function is not yet executed, it is only defined. Then you pass it into the "setTimeout":
window.setTimeout(myFunc, 50);
Which makes the "setTimeout" to execute that function after 50msec. And when it does, it will call waitForFnc(fnc)
.
Upvotes: 3