我需要一个通用的javascript“等待功能可用”

时间:2012-04-26 07:19:24

标签: javascript closures

我找到了这个优秀的代码段Make my userscript wait for other scripts to load,告诉我如何在调用函数之前等待函数可用。

目前我在我的脚本中有这个本地代码,我把它放在一起对我有用

waitForFnc();

function waitForFnc() {
    if (typeof Portal.Management_Init == "undefined") {
        window.setTimeout(waitForFnc, 50);
    }
    else {
        Portal.Management_Init();
    }
}

但是,我想写一个'waitForFnc'的通用版本,因为我需要在几个地方做同样的事情。像

这样的东西
waitForFnc(Portal.Management_Init);

function waitForFnc(fnc) {
    if (typeof fnc == "undefined") {
        window.setTimeout(waitForFnc(fnc), 50);
    }
    else {
       fnc();
    }
}

我传递函数的名称,当它可用时调用。上面的代码不起作用,但我不确定如何解决它。

此致 保罗

4 个答案:

答案 0 :(得分:3)

基本上,当执行这行代码时:window.setTimeout(waitForFnc(fnc), 50);,在设置超时之前评估“waitForFnc”。您需要将调用语句作为参数传递。

这是你如何做到的:

window.setTimeout(function() {waitForFnc(fnc);}, 50);

这样做,它定义了一个函数,就像你将它写入变量一样:

var myFunc = function() {
    waitForFnc(fnc);
};

此功能尚未执行,仅定义。然后将其传递给“setTimeout”:

window.setTimeout(myFunc, 50);

这使得“setTimeout”在50毫秒后执行该功能。如果确实如此,则会调用waitForFnc(fnc)

答案 1 :(得分:3)

您尝试做的事情存在一些潜在问题。如果在甚至定义Portal之前调用waitForFnc(),您将获得null属性访问异常。如果您正在尝试使用真正通用的解决方案,则可能必须使用eval()* gasp *

在我们处理它的时候,让我们添加支持将参数传递给我们正在等待的函数。

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]);

答案 2 :(得分:0)

在您的代码中替换:

window.setTimeout(waitForFnc(fnc), 50);

关闭:

window.setTimeout(function() {waitForFnc(fnc)}, 50);

但我可以问你为什么需要这么奇怪的代码?我宁愿期望有一个API允许注册一些回调:

Portal.onManagementInitAvailable(fn);

答案 3 :(得分:0)

根据您正在加载的内容,您可以利用require.js为您处理此问题;这基本上就是它的用途:http://requirejs.org/docs/why.html#9