web-dev-qa-db-fra.com

Tant que la variable n'est pas définie - attendez

J'ai un événement click déclenché automatiquement d'un autre endroit pour la première fois. Mon problème est qu'il s'exécute trop tôt, car les variables requises sont toujours définies par Flash et les services Web. Donc maintenant j'ai:

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

Le problème est que 5 secondes pour une personne avec une connexion Internet lente peuvent être trop rapides et inversement, pour une personne avec une connexion Internet rapide, c'est trop lent.

Alors, comment dois-je faire le délai ou le délai d'attente jusqu'à ce que someVariable soit défini?

40
JackLeo

Je préférerais ce code:

function checkVariable() {

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

 setTimeout(checkVariable, 1000);
17
Tushar Ahirrao

Ce qui suit va continuer à chercher un peu de variable jusqu'à ce qu'il soit trouvé. Il vérifie toutes les 0,25 secondes.

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

Voici un exemple où toute la logique d’attente jusqu’à ce que la variable soit définie est reportée à une fonction qui appelle ensuite un rappel qui fait tout ce que le programme doit faire. Si vous devez charger des variables avant de faire autre chose, c -ish moyen de le faire, donc vous séparez le chargement de variable de tout le reste, tout en assurant que «tout le reste» est essentiellement un rappel.

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

  });
3
Ollie H-M

Au lieu d'utiliser l'événement de chargement windows, utilisez l'événement ready du document.

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

Cela devrait se déclencher lorsque tout dans le DOM est prêt, y compris le contenu multimédia entièrement chargé.

3
Jamie Dixon

Avec Ecma Script 2017, vous pouvez utiliser asynchrone-wait et en même temps pour le faire.

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

De plus, vous n'avez pas à utiliser setTimeout dans ce cas, il vous suffit de rendre la fonction prête asynchrone ...

2
Toprak

Chemin plus court:

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

Vous pouvez également passer des arguments

2
tdmartin

Vous pouvez utiliser ceci:

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

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

Vous pourriez avoir Flash appeler la fonction quand c'est fait. Je ne suis pas sûr de ce que vous entendez par services Web. Je suppose que vous avez un code JavaScript appelant des services Web via Ajax, auquel cas vous sauriez quand ils se terminent. Dans le pire des cas, vous pourriez faire une boucle setTimeout qui vérifierait toutes les 100 ms environ.

Et la vérification de la définition ou non d'une variable peut être simplement if (myVariable) ou plus sûre: if(typeof myVariable == "undefined")

0
Milimetric
Object.defineProperty(window, 'propertyName', {
    set: value => {
        this._value = value;
        // someAction();
    },
    get: () => this._value
});

ou même si vous souhaitez simplement que cette propriété soit transmise en tant qu'argument à une fonction et n'avez pas besoin qu'elle soit définie sur un objet global:

Object.defineProperty(window, 'propertyName', { set: value => someAction(value) })

Cependant, comme dans votre exemple, vous semblez vouloir effectuer une action lors de la création d'un nœud, je vous suggère de regarder MutationObservers .

0
Przemek

J'ai voté @ - dnuttle's answer , mais j'ai fini par utiliser la stratégie suivante:

// 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();
});

Il est testé et fonctionne! ;)

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

0
Wallace Sidhrée