jQuery: espera / demora 1 segundo sin ejecutar código

129

No puedo hacer que el .delaymétodo funcione en jQuery:

$.delay(3000); // not working
$(queue).delay(3000); // not working

Estoy usando un ciclo while para esperar hasta que un valor de cambio incontrolado sea mayor o igual que otro y no puedo encontrar ninguna forma de detener la ejecución durante X segundos.

Brian Graham
fuente
intente usar setTimeout en la devolución de llamada
theshadowmonkey
¿Qué versión de jquery estás usando?
L7ColWinters
1
para eso no está diseñada la función de retraso, está diseñada para usarse entre eventos jquery en cola (como fade (). delay (). show ()). Necesita la función setTimeOut.
JoJa
@JoJa: Tiene razón en el punto principal, sin embargo, la forma sin argumento de mostrar (y ocultar) no utiliza la cola de efectos.
Jay Tomten
3
Por favor, indique lo que está tratando de lograr con la demora. Todo JavaScript se ejecuta en un solo hilo, y congelarlo durante X segundos puede causar una experiencia adversa para el usuario.
Dmitry Shkuropatsky

Respuestas:

176

$ .delay se usa para retrasar las animaciones en una cola, no para detener la ejecución.

En lugar de usar un ciclo while, debe llamar de forma recursiva a un método que realiza la verificación cada segundo usando setTimeout:

var check = function(){
    if(condition){
        // run when condition is met
    }
    else {
        setTimeout(check, 1000); // check again in a second
    }
}

check();
Justin Niessner
fuente
1
Creo que setTimeout es suficiente.
Jiemurat
3
Eres el hermano de la bomba, esto es exactamente lo que necesitaba para arreglar mi código.
jemiloii
@Jiemurat y cualquier otra persona en el futuro: setTimeout no interrumpe el flujo de ejecución. ¡El gran código de Niessner obtiene esto hasta que las condiciones se hicieron realidad!
Gabrer
Si no necesita romper el flujo de ejecución, simplemente puede usar setTimeout().
Joshua Pinter
siempre obtengo "el control no es una función", mi función de control tiene dos parámetros, sin embargo
Black
211

También puede retrasar algunas operaciones de esta manera:

setTimeout(function (){

  // Something you want delayed.

}, 5000); // How long do you want the delay to be (in milliseconds)? 
Matt Sich
fuente
77
Solo para su información, esto no interrumpe el flujo de ejecución, por lo que si necesita "detener todo" durante unos segundos, necesitará algo como lo que Niessner ha publicado.
Joshua Pinter
Sí ... es una devolución de llamada a la función y no se bloquea. Gracias por la respuesta, solucionó mi problema.
Bertus Kruger
Si la frecuencia es extremadamente corta y esperamos que esta función se ejecute para siempre, ¿finalmente volará la pila?
Suicide Bunny
16

ES6 setTimeout

setTimeout(() => {
  console.log("we waited 204586560000 ms to run this code, oh boy wowwoowee!");
}, 204586560000);

Editar: 204586560000 ms es el tiempo aproximado entre la pregunta original y esta respuesta ... suponiendo que calculé correctamente.

thedanotto
fuente
2
realmente agradable usar el tiempo aproximado de la pregunta original a esta respuesta
Fuzzybear
9

La delayfunción de jQuery está destinada a ser utilizada con efectos y colas de efectos, vea los delaydocumentos y el ejemplo en ellos:

$('#foo').slideUp(300).delay(800).fadeIn(400);

Si desea observar una variable para los cambios, puede hacer algo como

(function() {
    var observerInterval = setInterval(function() {
        if (/* check for changes here */) {
           clearInterval(observerInterval);
           // do something here
        }
    }, 1000);
})();
Julian D.
fuente
setInterval tiene un segundo parámetro obligatorio, el tiempo en milisegundos;)
sara_thepot
1
Gracias @ sara.potyscki, arreglado.
Julian D.
@JulianD. Gracias por esta sugerencia. Aterricé en esta pregunta mientras busco en Google una solución. Esto es exactamente lo que necesitaba para mi proyecto.
Cheryl Velez
8

JavaScript setTimeoutes una muy buena solución:

function funcx()
   {
   // your code here
   // break out here if needed
   setTimeout(funcx, 3000);
   }

funcx();

La delayfunción en jQuery se usa principalmente para retrasar animaciones en una cola de animación jQuery.

Jay Tomten
fuente
5

delay()no detiene el flujo de código y luego lo vuelve a ejecutar. No hay una forma práctica de hacerlo en JavaScript. Todo tiene que hacerse con funciones que aceptan devoluciones de llamada como las setTimeoutque otros han mencionado.

El propósito de jQuery delay()es hacer que una cola de animación espere antes de ejecutarse. Entonces, por ejemplo $(element).delay(3000).fadeIn(250);, el elemento se desvanecerá después de 3 segundos.

Nathan MacInnes
fuente
5

Solo javascript funcionará sin jQuery

<!DOCTYPE html>
<html>
    <head>
        <script>
            function sleep(miliseconds) {
                var currentTime = new Date().getTime();
                while (currentTime + miliseconds >= new Date().getTime()) {
                }
            }

            function hello() {
                sleep(5000);
                alert('Hello');
            }
            function hi() {
                sleep(10000);
                alert('Hi');
            }
        </script>
    </head>
    <body>
        <a href="#" onclick="hello();">Say me hello after 5 seconds </a>
        <br>
        <a href="#" onclick="hi();">Say me hi after 10 seconds </a>


    </body>
</html>
Faruk Omar
fuente
1
Hacer bucles para esperar en JavaScript es una mala idea. Toda la funcionalidad de JavaScript se detendrá mientras se ejecuta el bucle. Esto tendrá efectos secundarios imprevistos. Es mucho mejor usar funciones sin bloqueo como setTimeout ().
Kevin G.
4

Javascript es un lenguaje de programación asíncrono, por lo que no puede detener la ejecución por un tiempo; la única forma en que puede [pseudo] detener una ejecución es usando setTimeout () que no es un retraso sino una "devolución de llamada de función retrasada".

Fabio Buda
fuente
2

Si está utilizando las funciones de ES6 y está en una función asíncrona, puede detener efectivamente la ejecución del código por un tiempo determinado con esta función:

const delay = millis => new Promise((resolve, reject) => {
  setTimeout(_ => resolve(), millis)
});

Así es como lo usas:

await delay(5000);

Se detendrá la cantidad solicitada de milisegundos, pero solo si está en una función asíncrona . Ejemplo a continuación:

const myFunction = async function() {
  // first code block ...

  await delay(5000);

  // some more code, executed 5 seconds after the first code block finishes
}
Anthony De Smet
fuente