javascript - usar - setTimeout o setInterval?
timeout w3schools (19)
Por lo que puedo decir, estas dos piezas de JavaScript se comportan de la misma manera:
Opción A:
function myTimeoutFunction()
{
doStuff();
setTimeout(myTimeoutFunction, 1000);
}
myTimeoutFunction();
Opción B:
function myTimeoutFunction()
{
doStuff();
}
myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);
¿Hay alguna diferencia entre usar setTimeout y setInterval ?
¿Hay alguna diferencia?
Sí. Un tiempo de espera se ejecuta una cierta cantidad de tiempo después de llamar a setTimeout (); un Intervalo ejecuta una cierta cantidad de tiempo después del intervalo anterior activado.
Notará la diferencia si su función doStuff () tarda un poco en ejecutarse. Por ejemplo, si representamos una llamada a setTimeout / setInterval con .
, una activación del tiempo de espera / intervalo con *
y la ejecución del código JavaScript con [-----]
, las líneas de tiempo se ven así:
Timeout:
. * . * . * . * .
[--] [--] [--] [--]
Interval:
. * * * * * *
[--] [--] [--] [--] [--] [--]
La siguiente complicación es si un intervalo se dispara mientras JavaScript ya está ocupado haciendo algo (como manejar un intervalo anterior). En este caso, el intervalo se recuerda y ocurre tan pronto como el controlador anterior finaliza y devuelve el control al navegador. Por ejemplo, para un proceso doStuff () que a veces es corto ([-]) y a veces largo ([-----]):
. * * • * • * *
[-] [-----][-][-----][-][-] [-]
• representa un intervalo de activación que no pudo ejecutar su código de inmediato y en su lugar se hizo pendiente.
Así que los intervalos tratan de "ponerse al día" para volver a lo previsto. Pero, no hacen cola uno encima del otro: solo puede haber una ejecución pendiente por intervalo. (Si todos se pusieran en cola, ¡el navegador quedaría con una lista cada vez más amplia de ejecuciones pendientes!)
. * • • x • • x
[------][------][------][------]
x representa un intervalo de activación que no se pudo ejecutar o hacer pendiente, por lo que se descartó.
Si su función doStuff () suele tardar más tiempo en ejecutarse que el intervalo establecido para ella, el navegador consumirá el 100% de la CPU que intenta darle servicio y puede ser menos receptivo.
¿Cuál usas y por qué?
Chained-Timeout otorga una ranura garantizada de tiempo libre al navegador; Interval intenta asegurarse de que la función que está ejecutando se ejecute lo más cerca posible de sus horarios programados, a expensas de la disponibilidad de la IU del navegador.
Consideraría un intervalo para animaciones únicas. Quería ser lo más suave posible, mientras que los tiempos de espera encadenados son más corteses para las animaciones en curso que tendrían lugar todo el tiempo mientras se carga la página. Para usos menos exigentes (como un disparador de actualización trivial cada 30 segundos o algo así), puede usar cualquiera de los dos de forma segura.
En cuanto a la compatibilidad del navegador, setTimeout es anterior a setInterval, pero todos los navegadores con los que se encontrará hoy son compatibles con ambos. El último rezagado en muchos años fue IE Mobile en WinMo <6.5, pero espero que ahora también haya quedado atrás.
setInterval ()
setInterval()
es un método de ejecución de código basado en intervalos de tiempo que tiene la capacidad nativa de ejecutar repetidamente una secuencia de comandos especificada cuando se alcanza el intervalo. El autor del guión no debe anidarlo en su función de devolución de llamada para que se convierta en un bucle, ya que de forma predeterminada realiza un bucle. Seguirá disparándose en el intervalo a menos que llame a clearInterval()
.
Si desea hacer un bucle de código para animaciones o en un reloj, use setInterval()
.
function doStuff() {
alert("run your code here when time interval is reached");
}
var myTimer = setInterval(doStuff, 5000);
setTimeout ()
setTimeout()
es un método de ejecución de código basado en el tiempo que ejecutará un script solo una vez cuando se alcance el intervalo. No se repetirá de nuevo a menos que lo setTimeout()
para hacer un bucle en el script anidando el objeto setTimeout()
dentro de la función que llama a ejecutar. Si está orientado a bucle, seguirá disparando en el intervalo a menos que llame a clearTimeout()
.
function doStuff() {
alert("run your code here when time interval is reached");
}
var myTimer = setTimeout(doStuff, 5000);
Si desea que algo suceda una vez después de un período de tiempo específico, use setTimeout()
. Esto se debe a que solo se ejecuta una vez cuando se alcanza el intervalo especificado.
Básicamente intentan hacer lo mismo, pero el enfoque setInterval
será más preciso que el enfoque setTimeout
, ya que setTimeout
espera 1000 ms, ejecuta la función y luego establece otro tiempo de espera. Así que el período de espera es en realidad un poco más de 1000 ms (o mucho más si su función tarda mucho tiempo en ejecutarse).
Aunque se podría pensar que setInterval
se ejecutará exactamente cada 1000 ms, es importante tener en cuenta que setInterval
también se demorará, ya que JavaScript no es un lenguaje de múltiples hilos, lo que significa que, si hay otras partes del script en ejecución, el intervalo Habrá que esperar a que eso termine.
En este violín , puede ver claramente que el tiempo de espera se retrasará, mientras que el intervalo es casi todo el tiempo en casi 1 llamada / segundo (lo que el script está tratando de hacer). Si cambia la variable de velocidad en la parte superior a algo pequeño como 20 (lo que significa que intentará ejecutarse 50 veces por segundo), el intervalo nunca alcanzará un promedio de 50 iteraciones por segundo.
El retraso casi siempre es insignificante, pero si está programando algo realmente preciso, debe elegir un temporizador autoajustable (que esencialmente es un temporizador basado en el tiempo de espera que se ajusta constantemente para el retraso creado)
Bueno, setTimeout es mejor en una situación, como acabo de aprender. Siempre uso setInterval, que me queda por ejecutar en segundo plano durante más de media hora. Cuando volví a esa pestaña, la presentación de diapositivas (en la que se usaba el código) estaba cambiando muy rápidamente, en lugar de cada 5 segundos que debería tener. De hecho, vuelve a suceder cuando lo pruebo más y si es culpa del navegador o no, no es importante, porque con setTimeout esa situación es completamente imposible.
Creo que SetInterval
y SetTimeout
son diferentes. SetInterval
ejecuta el bloque de acuerdo con el tiempo establecido, mientras que SetTimeout
ejecuta el bloque de código una vez.
Pruebe este conjunto de códigos después de los segundos de cuenta atrás del tiempo de espera:
setInterval(function(e){
alert(''Ugbana Kelvin'');
}, 2000);
y luego intenta
setTimeout(function(e){
alert(''Ugbana Kelvin'');
}, 2000);
Puedes ver las diferencias por ti mismo.
Cuando ejecute alguna función dentro de setInterval, que funciona más tiempo que el tiempo de espera-> el navegador se bloqueará.
- Por ejemplo, doStuff () toma 1500 seg. para ser ejecutado y haces: setInterval (doStuff, 1000);
1) El navegador ejecuta doStuff () que tarda 1.5 segundos. para ser ejecutado
2) Después de ~ 1 segundo, intenta ejecutar doStuff () nuevamente. Pero el doStuff () anterior todavía se ejecuta- > así que el navegador agrega esta ejecución a la cola (para ejecutarse después de que se realiza primero).
3,4, ..) El mismo agregado a la cola de ejecución para las siguientes iteraciones, pero doStuff () de la anterior aún está en progreso ...
Como resultado, el navegador está bloqueado.
Para evitar este comportamiento, la mejor manera es ejecutar setTimeout dentro de setTimeout para emular setInterval .
Para corregir los tiempos de espera entre las llamadas a setTimeout, puede utilizar una alternativa autocorrectora a la técnica setInterval de JavaScript .
El setInterval hace que sea más fácil cancelar la ejecución futura de su código. Si usa setTimeout, debe hacer un seguimiento de la identificación del temporizador en caso de que desee cancelarlo más adelante.
var timerId = null;
function myTimeoutFunction()
{
doStuff();
timerId = setTimeout(myTimeoutFunction, 1000);
}
myTimeoutFunction();
// later on...
clearTimeout(timerId);
versus
function myTimeoutFunction()
{
doStuff();
}
myTimeoutFunction();
var timerId = setInterval(myTimeoutFunction, 1000);
// later on...
clearInterval(timerId);
He hecho una prueba simple de setInterval(func, milisec)
, porque tenía curiosidad por lo que sucede cuando el consumo de tiempo de función es mayor que la duración del intervalo.
setInterval
generalmente programará la siguiente iteración justo después del inicio de la iteración anterior, a menos que la función aún esté en curso . Si es así, setInterval
esperará hasta que la función termine. Tan pronto como sucede, la función se activa de nuevo, no hay que esperar para la próxima iteración según el programa (ya que estaría en condiciones sin función de tiempo excedido). Tampoco hay ninguna situación con iteraciones paralelas en ejecución.
He probado esto en Chrome v23. Espero que sea una implementación determinista en todos los navegadores modernos.
window.setInterval(function(start) {
console.log(''fired: '' + (new Date().getTime() - start));
wait();
}, 1000, new Date().getTime());
Salida de consola:
fired: 1000 + ~2500 ajax call -.
fired: 3522 <------------------''
fired: 6032
fired: 8540
fired: 11048
La función de wait
es solo una ayuda para el bloqueo de subprocesos: una llamada ajax síncrona que toma exactamente 2500 milisegundos de procesamiento en el lado del servidor:
function wait() {
$.ajax({
url: "...",
async: false
});
}
La diferencia es obvia en la consola:
La misma diferencia está en sus propósitos.
setInterval()
-> executes a function, over and over again, at specified time intervals
setTimeout()
-> executes a function, once, after waiting a specified number of milliseconds
Es tan simple como eso
Más detalles detallados aquí http://javascript.info/tutorial/settimeout-setinterval
Me parece que el método setTimeout
es más fácil de usar si desea cancelar el tiempo de espera:
function myTimeoutFunction() {
doStuff();
if (stillrunning) {
setTimeout(myTimeoutFunction, 1000);
}
}
myTimeoutFunction();
Además, si algo sale mal en la función, simplemente dejará de repetirse en el primer error de tiempo, en lugar de repetir el error cada segundo.
Para verlo de manera un poco diferente: setInterval asegura que un código se ejecute en cada intervalo dado (es decir, 1000 ms, o cuánto especifique), mientras que setTimeout establece el tiempo que "espera hasta" ejecuta el código. Y dado que se necesitan milisegundos adicionales para ejecutar el código, se agregan hasta 1000 ms y, por lo tanto, setTimeout se ejecuta nuevamente en momentos inexactos (más de 1000 ms).
Por ejemplo, los temporizadores / las cuentas regresivas no se hacen con setTimeout, se hacen con setInterval, para asegurar que no se demore y que el código se ejecute en el intervalo exacto dado.
Probablemente sería mejor reemplazar la primera función por esta
Opciones A ''
function myTimeoutFunction()
{
setTimeout(myTimeoutFunction, 1000);// At first
doStuff();
}
myTimeoutFunction();
¿No es así?
Puede validar la respuesta de Bobince usted mismo cuando ejecute el siguiente javascript o verifique este JSFiddle
<div id="timeout"></div>
<div id="interval"></div>
var timeout = 0;
var interval = 0;
function doTimeout(){
$(''#timeout'').html(timeout);
timeout++;
setTimeout(doTimeout, 1);
}
function doInterval(){
$(''#interval'').html(interval);
interval++;
}
$(function(){
doTimeout();
doInterval();
setInterval(doInterval, 1);
});
Simplemente agregue lo que ya se ha dicho, pero la versión setTimeout del código también alcanzará el Maximum call stack size
que impedirá que funcione. Dado que no hay un caso base para que la función recursiva se detenga, no se puede ejecutar para siempre.
Su código tendrá diferentes intervalos de ejecución, y en algunos proyectos, como los juegos en línea, no es aceptable. Primero, qué debe hacer para que su código funcione con los mismos intervalos, debe cambiar "myTimeoutFunction" a esto:
function myTimeoutFunction()
{
setTimeout(myTimeoutFunction, 1000);
doStuff();
}
myTimeoutFunction()
Después de este cambio, será igual a
function myTimeoutFunction()
{
doStuff();
}
myTimeoutFunction();
setInterval(myTimeoutFunction, 1000);
Pero, todavía no tendrá un resultado estable, porque JS es de un solo hilo. Por ahora, si el subproceso JS estará ocupado con algo, no podrá ejecutar la función de devolución de llamada y la ejecución se pospondrá entre 2 y 3 ms. Si tiene 60 ejecuciones por segundo, y cada vez que tenga un retraso aleatorio de 1-3 segundos, será absolutamente inaceptable (después de un minuto será de aproximadamente 7200 ms de retraso), y puedo recomendarle que use algo como esto:
function Timer(clb, timeout) {
this.clb = clb;
this.timeout = timeout;
this.stopTimeout = null;
this.precision = -1;
}
Timer.prototype.start = function() {
var me = this;
var now = new Date();
if(me.precision === -1) {
me.precision = now.getTime();
}
me.stopTimeout = setTimeout(function(){
me.start()
}, me.precision - now.getTime() + me.timeout);
me.precision += me.timeout;
me.clb();
};
Timer.prototype.stop = function() {
clearTimeout(this.stopTimeout);
this.precision = -1;
};
function myTimeoutFunction()
{
doStuff();
}
var timer = new Timer(myTimeoutFunction, 1000);
timer.start();
Este código garantizará un período de ejecución estable. Incluso el hilo estará ocupado, y su código se ejecutará después de 1005 msegundos, la próxima vez tendrá un tiempo de espera de 995 ms y el resultado será estable.
Tanto setInterval como setTimeout devuelven un ID de temporizador que puede utilizar para cancelar la ejecución, es decir, antes de que se activen los tiempos de espera. Para cancelar, llame a clearInterval o clearTimeout de esta forma:
var timeoutId = setTimeout(someFunction, 1000);
clearTimeout(timeoutId);
var intervalId = setInterval(someFunction, 1000),
clearInterval(intervalId);
Además, los tiempos de espera se cancelan automáticamente cuando abandona la página o cierra la ventana del navegador.
Yo uso setTimeout.
Aparentemente, la diferencia es que setTimeout llama al método una vez, setInterval lo llama repetidamente.
Aquí hay un buen artículo que explica la diferencia: Tutorial: temporizadores de JavaScript con setTimeout y setInterval
Este artículo dice que debe evitar setInterval si es posible, especialmente porque puede replicar su comportamiento con setTimeout y obtener algunos beneficios adicionales en el camino.