trastorno - Ejecute el script después de un retraso específico usando JavaScript
retraso de aprendizaje (12)
¿Por qué no puedes poner el código detrás de una promesa? (mecanografiado en la parte superior de mi cabeza)
new Promise(function(resolve, reject) {
setTimeout(resolve, 2000);
}).then(function() {
console.log(''do whatever you wanted to hold off on'');
});
¿Hay algún método de JavaScript similar al jQuery delay()
o wait()
(para retrasar la ejecución de un script durante un período de tiempo específico)?
Hay lo siguiente:
setTimeout(function, milliseconds);
función que se puede pasar el tiempo después del cual se ejecutará la función.
La respuesta simple es:
setTimeout(
function () {
x = 1;
}, 1000);
La función anterior espera 1 segundo (1000 ms) y luego establece x en 1. Obviamente, este es un ejemplo; puedes hacer lo que quieras dentro de la función anónima.
Me gustó mucho la explicación de Maurius (la respuesta más alta al alza) con los tres métodos diferentes para llamar a setTimeout
.
En mi código quiero navegar automática y automáticamente a la página anterior luego de completar un evento de guardado de AJAX. La finalización del evento guardado tiene una ligera animación en el CSS que indica que el guardado fue exitoso.
En mi código, encontré una diferencia entre los dos primeros ejemplos:
setTimeout(window.history.back(), 3000);
Éste no espera el tiempo de espera, se llama al back () casi de inmediato, sin importar el número que puse para la demora.
Sin embargo, cambiando esto a:
setTimeout(function() {window.history.back()}, 3000);
Esto hace exactamente lo que esperaba.
Esto no es específico de la operación back (), lo mismo ocurre con alert()
. Básicamente con la alert()
utilizada en el primer caso, el tiempo de retardo se ignora. Cuando descarto la ventana emergente, la animación del CSS continúa.
Por lo tanto, recomendaría el segundo o el tercer método que describe incluso si está usando funciones integradas y no está usando argumentos.
Necesita usar setTimeout y pasarle una función de devolución de llamada. La razón por la que no puedes usar sleep en javascript es porque bloquearías que toda la página hiciera algo mientras tanto. No es un buen plan. Utiliza el modelo de eventos de Javascript y mantente feliz. No luchar contra eso!
Para agregar los comentarios anteriores, me gustaría decir lo siguiente:
La función setTimeout()
en JavaScript no pausa la ejecución del script per se, sino que simplemente le dice al compilador que ejecute el código en algún momento en el futuro.
No hay una función que pueda detener la ejecución incorporada en JavaScript. Sin embargo, puede escribir su propia función que hace algo así como un ciclo incondicional hasta que llegue el momento utilizando la función Date()
y agregando el intervalo de tiempo que necesita.
Si realmente desea tener una función de delay
bloqueo (sincrónico) (por cualquier motivo), ¿por qué no hacer algo como esto?
<script type="text/javascript">
function delay(ms) {
var cur_d = new Date();
var cur_ticks = cur_d.getTime();
var ms_passed = 0;
while(ms_passed < ms) {
var d = new Date(); // Possible memory leak?
var ticks = d.getTime();
ms_passed = ticks - cur_ticks;
// d = null; // Prevent memory leak?
}
}
alert("2 sec delay")
delay(2000);
alert("done ... 500 ms delay")
delay(500);
alert("done");
</script>
Si solo necesita probar un retraso, puede usar esto:
function delay(ms) {
ms += new Date().getTime();
while (new Date() < ms){}
}
Y luego, si desea retrasar durante 2 segundos, lo hace:
delay(2000);
Sin embargo, podría no ser lo mejor para la producción. Más sobre eso en los comentarios
Solo para agregar a lo que todos los demás han dicho sobre setTimeout
: si desea llamar a una función con un parámetro en el futuro, debe configurar algunas llamadas de función anónimas.
Debe pasar la función como argumento para que se llame más tarde. En efecto, esto significa sin corchetes detrás del nombre. Lo siguiente llamará a la alerta de inmediato, y mostrará ''Hola mundo'':
var a = "world";
setTimeout(alert("Hello " + a), 2000);
Para solucionarlo, puede poner el nombre de una función (como lo hizo Flubba) o puede usar una función anónima. Si necesita pasar un parámetro, entonces debe usar una función anónima.
var a = "world";
setTimeout(function(){alert("Hello " + a)}, 2000);
a = "";
Pero si ejecuta ese código, notará que después de 2 segundos la ventana emergente dirá ''Hello ''. Esto se debe a que el valor de la variable a ha cambiado en esos dos segundos. Para que diga ''Hola mundo'' después de dos segundos, debe usar el siguiente fragmento de código:
function callback(a){
return function(){
alert("Hello " + a);
}
}
var a = "world";
setTimeout(callback(a), 2000);
a = "";
Esperará 2 segundos y luego emergerá ''Hola mundo''.
Solo para expandir un poco ... Puede ejecutar código directamente en la llamada a setTimeout
, pero como dice @patrick , normalmente asigna una función de devolución de llamada, como esta. El tiempo es milisegundos
setTimeout(func, 4000);
function func() {
alert(''Do stuff here'');
}
También puede usar window.setInterval() para ejecutar algún código repetidamente en un intervalo regular.
Tenía algunos comandos ajax que quería ejecutar con un retraso en el medio. Aquí hay un ejemplo simple de una forma de hacer eso. Sin embargo, estoy preparado para ser destrozado por mi enfoque poco convencional. :)
// Show current seconds and milliseconds
// (I know there are other ways, I was aiming for minimal code
// and fixed width.)
function secs()
{
var s = Date.now() + ""; s = s.substr(s.length - 5);
return s.substr(0, 2) + "." + s.substr(2);
}
// Log we''re loading
console.log("Loading: " + secs());
// Create a list of commands to execute
var cmds =
[
function() { console.log("A: " + secs()); },
function() { console.log("B: " + secs()); },
function() { console.log("C: " + secs()); },
function() { console.log("D: " + secs()); },
function() { console.log("E: " + secs()); },
function() { console.log("done: " + secs()); }
];
// Run each command with a second delay in between
var ms = 1000;
cmds.forEach(function(cmd, i)
{
setTimeout(cmd, ms * i);
});
// Log we''ve loaded (probably logged before first command)
console.log("Loaded: " + secs());
Puede copiar el bloque de código y pegarlo en una ventana de la consola y ver algo como:
Loading: 03.077
Loaded: 03.078
A: 03.079
B: 04.075
C: 05.075
D: 06.075
E: 07.076
done: 08.076