虽然未定义变量 - 等待

Jac*_*Leo 48 variables jquery timeout delay

我有一个click事件是第一次自动从另一个地方触发.我的问题是它运行得太快,因为Flash和Web服务仍然定义了所需的变量.所以现在我有:

(function ($) {
    $(window).load(function(){
        setTimeout(function(){
            $('a.play').trigger("click");
        }, 5000);
    });
})(jQuery);
Run Code Online (Sandbox Code Playgroud)

问题是互联网连接速度慢的人5秒钟可能太快,反之亦然,对于网速较快的人来说,速度太慢.

那么在someVariable定义之前我应该​​怎么做延迟或超时?

dnu*_*tle 91

以下将继续寻找someVariable,直到找到它为止.它每0.25秒检查一次.

function waitForElement(){
    if(typeof someVariable !== "undefined"){
        //variable exists, do what you want
    }
    else{
        setTimeout(waitForElement, 250);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 额外的功能是不必要的.做`setTimeout(waitForElement,250);` (8认同)
  • 我应该添加评论表明"准备好"可能更好; 我的解决方案可以使用或不使用jQuery. (3认同)
  • 我知道这很旧,但我今天偶然发现了这个。包装函数并不是多余的。它围绕代码创建一个闭包,创建一个保持其私有的模块。这是一种很好的做法,可以防止全局窗口被不必要的代码堵塞。 (3认同)
  • `setInterval()`似乎更适合这里 (2认同)
  • setInterval() 是错误的。一旦定义了 someVariable,就不需要继续调用该函数。 (2认同)

Tus*_*rao 21

我更喜欢这段代码:

function checkVariable() {

   if (variableLoaded == true) {
       // Here is your next action
   }
 }

 setTimeout(checkVariable, 1000);
Run Code Online (Sandbox Code Playgroud)

  • 我把它与`typeof someVariable!=='undefined'`结合起来,而且我不得不使用这里的信息:http://stackoverflow.com/questions/1055767/why-can-i-not-define-functions-in -jquerys文档就绪 (4认同)
  • 这不是一个好的解决方案,因为任何进程或dom的加载可能需要超过1000毫秒,这就打破了流程. (3认同)

Cym*_*men 10

我更喜欢这样简单的事情:

function waitFor(variable, callback) {
  var interval = setInterval(function() {
    if (window[variable]) {
      clearInterval(interval);
      callback();
    }
  }, 200);
}
Run Code Online (Sandbox Code Playgroud)

然后将它与您的示例变量一起使用someVariable

waitFor('someVariable', function() {
  // do something here now that someVariable is defined
});
Run Code Online (Sandbox Code Playgroud)

请注意,您可以进行各种调整。在上面的setInterval调用中,我传递200了间隔函数应该运行的频率。在检查变量之前,还有一段固有的延迟时间(~200 毫秒)——在某些情况下,立即检查它是很好的,这样就没有延迟。


Top*_*rak 8

使用Ecma Script 2017,您可以使用async-await和while一起执行此操作,而不会崩溃或锁定程序,即使变量永远不会为真

//First define some delay function which is called from async function
function __delay__(timer) {
    return new Promise(resolve => {
        timer = timer || 2000;
        setTimeout(function () {
            resolve();
        }, timer);
    });
};

//Then Declare Some Variable Global or In Scope
//Depends on you
let Variable = false;

//And define what ever you want with async fuction
async function some() {
    while (!Variable)
        await __delay__(1000);

    //...code here because when Variable = true this function will
};
////////////////////////////////////////////////////////////
//In Your Case
//1.Define Global Variable For Check Statement
//2.Convert function to async like below

var isContinue = false;
setTimeout(async function () {
    //STOPT THE FUNCTION UNTIL CONDITION IS CORRECT
    while (!isContinue)
        await __delay__(1000);

    //WHEN CONDITION IS CORRECT THEN TRIGGER WILL CLICKED
    $('a.play').trigger("click");
}, 1);
/////////////////////////////////////////////////////////////
Run Code Online (Sandbox Code Playgroud)

同样在这种情况下,您不必使用setTimeout,只需将就绪函数设为异步...


Val*_*len 7

async, await实施,对@Toprak的答案进行了改进

(async() => {
    console.log("waiting for variable");
    while(!window.hasOwnProperty("myVar")) // define the condition as you like
        await new Promise(resolve => setTimeout(resolve, 1000));
    console.log("variable is defined");
})();
console.log("above code doesn't block main function stack");
Run Code Online (Sandbox Code Playgroud)

在重新审查OP的问题之后。实际上,有一种更好的方法可以实现预期的目标:“变量集回调”。尽管以下代码仅在所需变量由对象(或窗口)封装而不是由let或声明的情况下才有效var(我留下了第一个答案,因为我只是对现有答案进行了改进,而没有实际阅读原始问题):

let obj = encapsulatedObject || window;
Object.defineProperty(obj, "myVar", {
    configurable: true,
    set(v){
        Object.defineProperty(obj, "myVar", {
            configurable: true, enumerable: true, writable: true, value: v });
        console.log("window.myVar is defined");
    }
});
Run Code Online (Sandbox Code Playgroud)

参见Object.defineProperty 或使用es6代理(这可能是过大的)