jQuery 虽然未定义变量 - 等待

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7307983/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 23:40:44  来源:igfitidea点击:

While variable is not defined - wait

jqueryvariablestimeoutdelay

提问by HymanLeo

I have a clickevent that is triggered from another place automatically for the first time. My problem is that it runs too soon, since the required variables are still being defined by Flash and web services. So right now I have:

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

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

The problem is that 5 seconds for a person with a slow internet connection could be too fast and vice versa, for a person with a fast internet connection, it's too slow.

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

So how should I do the delay or timeout until someVariableis defined?

那么在someVariable定义之前我应该​​如何进行延迟或超时呢?

采纳答案by Tushar Ahirrao

I would prefer this code:

我更喜欢这个代码:

function checkVariable() {

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

 setTimeout(checkVariable, 1000);

回答by dnuttle

The following will keep looking for someVariable until it is found. It checks every 0.25 seconds.

下面将继续寻找 someVariable 直到找到。它每 0.25 秒检查一次。

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

回答by Valen

async, awaitimplementation, improvement over @Toprak's answer

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


After revisiting the OP's question. There is actually a better way to implement what was intended: "variable set callback". Although the below code only works if the desired variable is encapsulated by an object (or window) instead of declared by letor var(I left the first answer because I was just doing improvement over existing answers without actually reading the original question):

在重新审视OP的问题之后。实际上有一种更好的方法来实现预期目的:“变量集回调”。尽管以下代码仅在所需变量由对象(或窗口)封装而不是由letor声明时才有效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");
    }
});

see Object.definePropertyor use es6 proxy(which is probably overkill)

请参阅Object.defineProperty或使用es6 代理(这可能是矫枉过正)

回答by Toprak

With Ecma Script 2017 You can use async-await and while together to do that And while will not crash or lock the program even variable never be true

使用 Ecma Script 2017 您可以使用 async-await 和 while 一起来做到这一点并且 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);
/////////////////////////////////////////////////////////////

Also you don't have to use setTimeout in this case just make ready function asynchronous...

此外,在这种情况下您不必使用 setTimeout 只需使就绪函数异步...

回答by Ollie H-M

Here's an example where all the logic for waiting until the variable is set gets deferred to a function which then invokes a callback that does everything else the program needs to do - if you need to load variables before doing anything else, this feels like a neat-ish way to do it, so you're separating the variable loading from everything else, while still ensuring 'everything else' is essentially a callback.

这是一个示例,其中所有等待变量设置的逻辑都被推迟到一个函数,该函数然后调用一个回调来完成程序需要做的所有其他事情——如果你需要在做任何其他事情之前加载变量,这感觉就像一个整洁的-ish 的方式来做到这一点,所以你将变量加载与其他一切分开,同时仍然确保“其他一切”本质上是一个回调。

var loadUser = function(everythingElse){
    var interval = setInterval(function(){
      if(typeof CurrentUser.name !== 'undefined'){
        $scope.username = CurrentUser.name;
        clearInterval(interval);
        everythingElse();
      }
    },1);
  };

  loadUser(function(){

    //everything else

  });

回答by Vladica Savic

You can use this:

你可以使用这个:

var refreshIntervalId = null;
refreshIntervalId = setInterval(checkIfVariableIsSet, 1000);

var checkIfVariableIsSet = function()
{
    if(typeof someVariable !== 'undefined'){
        $('a.play').trigger("click");
        clearInterval(refreshIntervalId);
    }
};

回答by tdmartin

Shorter way:

更短的方法:

   var queue = function (args){
      typeof variableToCheck !== "undefined"? doSomething(args) : setTimeout(function () {queue(args)}, 2000);
};

You can also pass arguments

你也可以传递参数

回答by Jamie Dixon

Instead of using the windows load event use the ready event on the document.

不使用 windows load 事件,而是使用文档上的 ready 事件。

$(document).ready(function(){[...]});

This should fire when everything in the DOM is ready to go, including media content fully loaded.

这应该在 DOM 中的所有内容都准备就绪时触发,包括完全加载的媒体内容。

回答by Wallace Sidhrée

I have upvoted @dnuttle's answer, but ended up using the following strategy:

我对@dnuttle 的回答投了赞成票,但最终使用了以下策略:

// On doc ready for modern browsers
document.addEventListener('DOMContentLoaded', (e) => {
  // Scope all logic related to what you want to achieve by using a function
  const waitForMyFunction = () => {
    // Use a timeout id to identify your process and purge it when it's no longer needed
    let timeoutID;
    // Check if your function is defined, in this case by checking its type
    if (typeof myFunction === 'function') {
      // We no longer need to wait, purge the timeout id
      window.clearTimeout(timeoutID);
      // 'myFunction' is defined, invoke it with parameters, if any
      myFunction('param1', 'param2');
    } else {
      // 'myFunction' is undefined, try again in 0.25 secs
      timeoutID = window.setTimeout(waitForMyFunction, 250);
    }
  };
  // Initialize
  waitForMyFunction();
});

It is tested and working! ;)

它已经过测试和工作!;)

Gist: https://gist.github.com/dreamyguy/f319f0b2bffb1f812cf8b7cae4abb47c

要点:https: //gist.github.com/dreamyguy/f319f0b2bffb1f812cf8b7cae4abb47c

回答by Cymen

I prefer something simple like this:

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

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

And then to use it with your example variable of someVariable:

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

waitFor('someVariable', function() {
  // do something here now that someVariable is defined
});

Note that there are various tweaks you can do. In the above setIntervalcall, I've passed 200as how often the interval function should run. There is also an inherent delay of that amount of time (~200ms) before the variable is checked for -- in some cases, it's nice to check for it right away so there is no delay.

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