Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I need a generic javascript "wait for function to be available"

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

like image 731
Paul Marsden Avatar asked Apr 26 '12 07:04

Paul Marsden


People also ask

How do you make a function wait in JavaScript?

Use setTimeout() to run a function after a single delay, and cancel that delay at any time with clearTimeout() . Use setInterval() to run a function many times with a delay before each execution, and cancel those repeated executions with clearInterval() .

How do you wait for a function?

Wait for function to finish using async/await keywords As you already know from the Promise explanation above, you need to chain the call to the function that returns a Promise using then/catch functions. The await keyword allows you to wait until the Promise object is resolved or rejected: await first(); second();

How do you wait for a function to return?

async and await Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.


2 Answers

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]);
like image 119
jordancpaul Avatar answered Oct 04 '22 15:10

jordancpaul


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).

like image 26
bezmax Avatar answered Oct 04 '22 15:10

bezmax