2009-07-26 20 views
51

Necesito agregar un retraso de aproximadamente 100 milisegundos a mi código Javascript pero no quiero usar la función setTimeout del objeto window y no quiero usar un bucle ocupado. ¿Alguien tiene alguna sugerencia?Poner un retraso en Javascript

+15

Puede explicar por qué no es apropiado setTimeout/no cumple con sus necesidades? – eyelidlessness

Respuesta

110

Desafortunadamente, setTimeout() es la única manera fiable (no la única, pero la única manera confiable ) para hacer una pausa en la ejecución del script sin bloquear la interfaz de usuario.

No es tan difícil de utilizar realmente, en lugar de escribir esto:

var x = 1; 

// Place mysterious code that blocks the thread for 100 ms. 

x = x * 3 + 2; 
var y = x/2; 

que utilizan setTimeout() volver a escribir de esta manera:

var x = 1; 
var y = null; // To keep under proper scope 

setTimeout(function() { 
    x = x * 3 + 2; 
    y = x/2; 
}, 100); 

entiendo que el uso de setTimeout() implica más pensamiento que una función deseable sleep(), pero desafortunadamente la última no existe. Muchas soluciones están ahí para tratar de implementar tales funciones. Algunas mediante bucles ocupados:

function sleep(milliseconds) { 
    var start = new Date().getTime(); 
    for (var i = 0; i < 1e7; i++) { 
    if ((new Date().getTime() - start) > milliseconds){ 
     break; 
    } 
    } 
} 

otros using an XMLHttpRequest tied with a server script that sleeps for a amount of time before returning a result.

Desafortunadamente, esas son soluciones temporales y es probable que causen otros problemas (como congelar navegadores). Se recomienda simplemente seguir con la forma recomendada, que es setTimeout()).

+2

Utilizo NoScript en mi computadora portátil precisamente porque la gente usa funciones como esa función de suspensión u otros bucles apretados inútiles. De lo contrario, de repente me quema un agujero en el regazo. –

+3

** @ James M.:** Totalmente de acuerdo ... Nunca entendí por qué hay un gran estigma alrededor de 'setTimeout()'. –

+2

No creo que setTimeout() tenga ningún estigma que lo rodee, es solo que no siempre produce el efecto deseado fácilmente. Digamos, por ejemplo, si desea inactivar el procesador durante un corto período de tiempo mientras se encuentra en un ciclo de proceso intensivo para evitar bloquear el navegador. Lograr este resultado con setTimeout puede ser difícil para programadores de JavaScript inexpertos. – KingRadical

2

This thread tiene una buena discusión y una solución útil:

function pause(iMilliseconds) 
{ 
    var sDialogScript = 'window.setTimeout(function() { window.close(); }, ' + iMilliseconds + ');'; 
    window.showModalDialog('javascript:document.writeln ("<script>' + sDialogScript + '<' + '/script>")'); 
} 

Por desgracia, parece que esto no funciona en algunas versiones de IE, pero el hilo tiene muchas otras propuestas dignas si eso resulta ser una problema para usted.

+2

Parece una solución a la espera de un problema. No puedo pensar en una sola situación en la que 'setTimeout' no haga su trabajo. Pero +1 para la creatividad. :) –

3

En realidad, solo setTimeout está bien para ese trabajo y normalmente no puede establecer retrasos exactos con métodos no determinados como bucles de ocupado.

+0

No puede pausar el intérprete js con setTimeout. –

+0

Solo puede llamar a una función después de un retraso. setTimeout no es 'bloqueo'. El resto del código funciona como se supone que debe hacerlo. –

11

Acabo de tener un problema donde tuve que resolver esto correctamente.

A través de Ajax, un script recibe X (0-10) mensajes. Lo que quería hacer: Agregue un mensaje al DOM cada 10 segundos.

el código terminé con:

$.each(messages, function(idx, el){ 
    window.setTimeout(function(){ 
    doSomething(el); 
    },Math.floor(idx+1)*10000); 
}); 

Básicamente, pensamos en los tiempos de espera como una "línea de tiempo" de su script.

Esto es lo que queremos código:

DoSomething(); 
WaitAndDoNothing(5000); 
DoSomethingOther(); 
WaitAndDoNothing(5000); 
DoEvenMore(); 

Esto es cómo tenemos que dirán a los javascript:

At Runtime 0 : DoSomething(); 
At Runtime 5000 : DoSomethingOther(); 
At Runtime 10000: DoEvenMore(); 

Espero que esto ayude.

+0

Gracias por la respuesta que explica el comportamiento de SetTimeOut. El problema es que más tarde, cuando el código es largo o depende de las respuestas del servidor, es difícil incluso visualizar la línea de tiempo real en segundos. –

-5

Use una función AJAX que llamará a una página php sincrónicamente y luego en esa página puede poner la función php usleep() que actuará como un retraso.

function delay(t){ 

var xmlhttp; 

if (window.XMLHttpRequest) 

{// code for IE7+, Firefox, Chrome, Opera, Safari 

xmlhttp=new XMLHttpRequest(); 

} 

else 

{// code for IE6, IE5 

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 

} 

xmlhttp.open("POST","http://www.hklabs.org/files/delay.php?time="+t,false); 

//This will call the page named delay.php and the response will be sent to a division with ID as "response" 

xmlhttp.send(); 

document.getElementById("response").innerHTML=xmlhttp.responseText; 

} 

http://www.hklabs.org/articles/put-delay-in-javascript

+4

formatee el código para que sea legible – kleopatra

+9

No se olvide de los conceptos básicos del diseño web. El principio fundamental es reducir la carga del servidor tanto como sea posible. Para un simple retraso, solicita una página del servidor infinitas veces. Solo piensa en lo que estás haciendo aquí. –

Cuestiones relacionadas