Mientras que la variable no está definida – esperar

Tengo un click evento que se activa desde otro lugar automáticamente por primera vez. Mi problema es que se ejecuta demasiado pronto, ya que las variables están siendo definidos por el Flash de la web y de los servicios. Así que ahora tengo:

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

El problema es que a los 5 segundos de una persona con una conexión lenta a internet podría ser demasiado rápido, y viceversa, para una persona con una conexión rápida a internet, es demasiado lento.

Entonces, ¿cómo debo hacer el retraso o tiempo de espera hasta que someVariable se define?

  • No hay «listos» de evento que usted pueda reaccionar?
  • Hmm, no hay forma genérica para decir «espere hasta que cierta variable se define» (en mudo aplicación sería la comprobación de que cada X milisegundos cada vez que la variable está definida aún). Sin embargo, si las variables que estamos esperando son establecidas por el (me refiero a administrado por usted) del código, a continuación, puede definir un nombre de función (una devolución de llamada) que será llamado justo después de la deseada definición de variable.
  • No debe ser ver -o algo así – método de existir en jQuery.
InformationsquelleAutor JackLeo | 2011-09-05

11 Kommentare

  1. 21

    Yo prefiero este código:

    function checkVariable() {
    
       if (variableLoaded == true) {
           //Here is your next action
       }
     }
    
     setTimeout(checkVariable, 1000);
    • He combinado esto con typeof someVariable !== 'undefined', y también tuve que usar la info de aquí: stackoverflow.com/questions/1055767/…
    • esta no es una buena solución, ya que la carga de cualquier proceso o dom puede tomar más de 1000ms, entonces esto interrumpe el flujo.
  2. 90

    El siguiente va a seguir buscando someVariable hasta que se encuentra. Comprueba cada 0,25 segundos.

    function waitForElement(){
        if(typeof someVariable !== "undefined"){
            //variable exists, do what you want
        }
        else{
            setTimeout(waitForElement, 250);
        }
    }
    • Debo añadir el comentario que sugiere «listo» es probablemente mejor; mi solución puede funcionar con o sin jQuery.
    • La función adicional es innecesaria. Hacer setTimeout(waitForElement,250);
    • Verdadero. Yo tiendo a usar funciones anónimas como una cuestión de rutina, debido a que con frecuencia tengo que ser capaz de pasar los valores de parámetro de vuelta a los exteriores de la función.
    • Nada de esto es necesario aquí. La función de contenedor es claramente superfluo. Usted sabe, un BESO/YAGNI. 🙂
    • Ya he acordado con usted.
    • setInterval() parece un mejor ajuste aquí
    • setInterval() sería un error. No necesita seguir llamando a la función una vez someVariable está definido.
    • ¿Cómo puedo hacer esta una función anónima? PS: Google me llevó aquí.
    • Sé que esto es viejo, pero me topé con esto hoy. La función de contenedor no es superflua. Crea un cierre de todo el código de la creación de un módulo que se mantiene en privado. Esa es una buena práctica y mantiene la ventana global de ser obstruidos con código innecesario.
    • setInterval() no es exactamente mal, pero usted tendría que llamar a clearInterval() una vez dentro del ‘si’ condición.

  3. 6

    Con Ecma Script 2017 puede utilizar async-esperan y mientras juntos para hacer que
    Y mientras no se colgará o bloquear el programa aún variable nunca será verdad

    JS:

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

    También usted no tiene que usar setTimeout en este caso acaba de hacer el listo de la función asíncrona…

    • algunos tedioso código en el setTimeout() sección, no he hecho: setTimeout(resolve, timer) en __delay__ recordar resolve sí es invocable y setTimeout() sólo se necesita una exigible para el primer argumento, no tiene que ajustar resolve una vez más. código completo: function delay(timer=2000){ return new Promise(resolve => setTimeout(resolve, timer)); } limpio.
    • como si en mi respuesta
  4. 4

    async, await implementación, mejora en @Toprak la respuesta

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

    Después de revisar el OP pregunta. De hecho, hay una mejor manera de poner en práctica lo que era la intención: «conjunto de variables de devolución de llamada». Aunque el código de abajo, sólo funciona si la variable está encapsulado en un objeto (o ventana) en lugar de declarada por let o var (me fui de la primera respuesta, porque yo sólo estaba haciendo mejora con respecto a las respuestas sin leer la pregunta original):

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

    ver Objeto.defineProperty
    o uso es6 proxy (que es probablemente una exageración)

  5. 3

    Aquí un ejemplo en el que toda la lógica para esperar hasta que se establece la variable obtiene diferida a una función que se invoca una devolución de llamada que se hace todo lo demás el programa necesita hacer si usted necesita para cargar variables antes de hacer nada, esto se siente como una casa-ish manera de hacerlo, así que usted es la separación de la variable de carga de todo lo demás, mientras que asegura que ‘todo lo demás’ es esencialmente una devolución de llamada.

    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
    
      });
  6. 2

    Lugar de utilizar la carga de windows caso uso el evento preparado en el documento.

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

    Esto debe fuego cuando todo en el DOM está listo para ir, incluyendo los medios de comunicación el contenido cargado completamente.

    • Esto funcionará, a menos que la existencia de someVariable es el resultado de una llamada ajax. Las llamadas Ajax puede ser (probablemente van a ser completado después de la llamada a lista.
    • Nope, de que existe una variable sólo después de algún tiempo. Yo uso (window).load porque vi un post aquí que está siendo cargado después (document).ready. Esto último para mí es mejor en este caso.
    • Yep. Dado que el escenario podría disparar el JS acontecimientos de su éxito controlador en la petición ajax. Afaik esto se puede hacer desde Flash a JS.
    • Esto no funciona si el script en cuestión y el script que define la variable uso $(document).listo y el script que define la variable se incluye después de la secuencia de comandos que utiliza.
    • Documento preparado es despedido después de que DOM se ha descargado, no los medios de comunicación. Si tienes que esperar a que los medios de comunicación para ser descargado, utilice la ventana de carga.
  7. 2

    Usted puede utilizar esta:

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

    Camino más corto:

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

    También puede pasar argumentos

  9. 0

    Podría tener Flash llamar a la función cuando se hace. No estoy seguro de lo que quieres decir con servicios web. Supongo que tiene el código JavaScript de llamar a los servicios web a través de Ajax, en cuyo caso usted sabe cuando terminan. En el peor de los casos, usted podría hacer un bucle de setTimeout que comprobar cada 100 ms o menos.

    Y la comprobación de si o no se define una variable puede ser sólo if (myVariable) o más seguro: if(typeof myVariable == "undefined")

  10. 0

    He upvoted @dnuttle del respuesta, pero terminó con la siguiente estrategia:

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

    Es probado y funcionando! 😉

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

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

    o incluso si lo que desea esta propiedad se pasa como argumento a una función, y no lo necesita para ser definido en un objeto global:

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

    Sin embargo, dado que en su ejemplo, usted parece querer llevar a cabo una acción sobre la creación de un nodo, le sugiero que eche un vistazo a MutationObservers.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea