setInterval()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
El método setInterval()
, ofrecido en las interfaces Window
y Worker
, llama a una función o ejecuta un fragmento de código de forma reiterada, con un retardo de tiempo fijo entre cada llamada.
Este método devuelve un ID de intervalo que lo identifica de forma única, de ese modo, el intervalo puede ser eliminado más tarde llamando a clearInterval()
.
Sintaxis
setInterval(code);
setInterval(code, delay);
setInterval(func);
setInterval(func, delay, arg0);
setInterval(func, delay, arg0, arg1);
setInterval(func, delay, arg0, arg1, /* ..., */ argN);
Parámetros
func
-
Una función
function
que se ejecuta cada cierto tiempo. El tiempo lo determinadelay
, estando éste en milisegundos. La primera ejecución ocurre tras el tiempo determinado pordelay
. code
-
Una sintaxis especial que permite incluir una cadena en lugar de una función, la cual es compilada y ejecutada cada
delay
milisegundos. Se recomienda no usar esta sintaxis, por la misma razón que hace que el uso deeval()
sea un riesgo de seguridad. delay
Opcional-
El tiempo en milisegundos (milésimas de segundo) que el temporizador debe retrasar cada ejecución de la función o código especificado. Si no se especifica ninguno, por defecto es 0. Ver el apartado Delay restrictions descrito más abajo para más detalles sobre el rango de valores de retardo (delay) permitido.
arg0, ..., argN
Opcional-
Argumentos adicionales que se pasan a la función especificada por func una vez que el temporizador expira.
Valor de retorno
El intervalID
devuelto es un valor numérico, diferente a 0, que identifica el temporizador creado para poder realizar la llamada a setInterval()
. Este valor puede ser pasado a clearInterval()
para cancelar el intervalo.
Puede ser útil tener en cuenta que setInterval()
y setTimeout()
comparten el mismo grupo de IDs. También es importante saber que clearInterval()
y clearTimeout()
técnicamente pueden ser utilizados indistintamente. Sin embargo, para mayor claridad siempre debe tratar de hacerlos coincidir, evitando así confusiones al mantener su código.
Nota:
El argumento delay
se convierte en un número entero de 32 bits con signo. Efectivamente, esto limita delay
a 2.147,483,647 milisegundos, ya que es especificado en el IDL como un número entero con signo.
Ejemplos
Ejemplo 1: Sintaxis básica
El siguiente ejemplo muestra la sintaxis básica de setInterval()
var intervalID = setInterval(myCallback, 500, "parámetro 1", "parámetro 2");
function myCallback(a, b) {
// Tu código debe ir aquí
// Los parámetros son totalmente opcionales
console.log(a);
console.log(b);
}
Ejemplo 2: Alternando dos colores
El siguiente ejemplo llama a la función flashtext()
una vez por segundo hasta que el botón Stop sea pulsado.
HTML
<div id="my_box">
<h3>Hello World</h3>
</div>
<button id="start">Start</button>
<button id="stop">Stop</button>
CSS
.go {
color: green;
}
.stop {
color: red;
}
JavaScript
// variable para almacenar nuestro intervalID
let nIntervId;
function changeColor() {
// comprobar si ya se ha configurado un intervalo
if (!nIntervId) {
nIntervId = setInterval(flashText, 1000);
}
}
function flashText() {
const oElem = document.getElementById("my_box");
if (oElem.className === "go") {
oElem.className = "stop";
} else {
oElem.className = "go";
}
}
function stopTextColor() {
clearInterval(nIntervId);
// liberar nuestro inervalId de la variable
nIntervId = null;
}
document.getElementById("start").addEventListener("click", changeColor);
document.getElementById("stop").addEventListener("click", stopTextColor);
Result
Véase también: clearInterval()
.
El problema con "this"
Cuando le pasas un método a setInterval()
o cualquier otra función, ésta será invocada con el valor de this
incorrecto. Este problema es explicado en detalle en la JavaScript reference.
Explicación
El código ejecutado por setInterval
se ejecuta en un contexto de ejecución distinto al de la función desde la que fue llamado. Como consecuencia, la palabra clave this
para la función llamada se establece en el objeto window
(u objeto global
), que no es el mismo contexto de ejecución del valor this
de la función que llamó a setInterval()
. Véase el siguiente ejemplo en el que se utiliza setTimeout()
en lugar de setInterval()
. El problema con this
es el mismo en ambos temporizadores:
myArray = ["zero", "one", "two"];
myArray.myMethod = function (sProperty) {
alert(arguments.length > 0 ? this[sProperty] : this);
};
myArray.myMethod(); // imprime "zero, one, two"
myArray.myMethod(1); // imprime "one"
setTimeout(myArray.myMethod, 1000); // imprime "[object Window]" después de un segundo
setTimeout(myArray.myMethod, 1500, "1"); // imprime "undefined" después de 1,5 segundos
// pasar el objeto 'this' con .cal no funcionará
// porque esto cambiará el valor de 'this' dentro del propio
// setTimeout, mientras que nosotros queremos cambiar el valor
// de 'this' dentro de myArray.myMethod. De hecho, será un error
// porque el código de setTimeout espera que 'this' sea el
// objeto ventana:
setTimeout.call(myArray, myArray.myMethod, 2000); // error:
// "NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on
// WrappedNative prototype object"
setTimeout.call(myArray, myArray.myMethod, 2500, 2); //mismo
// error
Como puede ver, no hay formas de pasar el objeto this
a la función de devolución de llamada o callback en código JavaScript legacy.
Una posible solución
Todos los entornos de ejecución modernos de JavaScript (en navegadores y otros lugares) soportan arrow functions, con this
léxico, lo que nos permite escribir setInterval( () => this.myMethod)
si estamos dentro del método myArray
.
Si necesita soporte para IE, utilice el método Function.prototype.bind
, que le permite especificar el valor que debe ser usado como this
para todas las llamadas a una función dada. Esto le permite fácilmente evitar los problemas en los que no está claro cual será this
dependiendo del contexto desde el que se llamó a la función.
Notas sobre su uso
La función setInterval()
se utiliza comúnmente para establecer un retardo en funciones que son ejecutadas una y otra vez, como por ejemplo las animaciones. Puede cancelar el intervalo utilizando clearInterval()
.
Si desea que su función sea llamada una vez después del retardo especificado utilice setTimeout()
.
Restricciones en el retardo
Es posible anidar intervalos; Es decir, la llamada de retorno de setInterval()
puede llamar a su vez a otro setInterval()
para iniciar otro intervalo, y que este sea ejecutado aunque el primero siga corriendo aún. Para mitigar el impacto potencial que esto puede tener en el rendimiento, una vez que los intervalos son anidados más allá de cinco niveles de profundidad, el navegador impondrá automáticamente un valor mínimo de cuatro milisegundos para el intervalo. Intenta especificar un valor menor a cuatro ms en llamadas profundamente anidadas a setInterval()
. Estas serán fijadas a 4 ms.
Los navegadores pueden imponer valores mínimos aún más estrictos para el intervalo en determinadas circunstancias, aunque no deberían ser habituales. Tenga también en cuenta que la cantidad real de tiempo que transcurre entre las llamadas a la función callback puede ser mayor que el propio retardo (delay); Ver Reasons for delays longer than specified para ver ejemplos.
Garantizar que la duración de la ejecución sea inferior a la frecuecia del intervalo
Si existe la posibilidad de que su lógica pueda tardar más en ejecutarse que el tiempo de intervalo, se recomienda llamar recursivamente a una función nombrada utilizando setTimeout()
. Por ejemplo, si utiliza setInterval()
para sondear un servidor remoto cada cinco segundos, la latencia de la red, un servidor que no responde y una serie de otros problemas podrían impedir que la solicitud se complete en el tiempo asignado. Debido a esto, es posible que se encuentre con peticiones XHR en cola que no necesariamente retornarán en orden.
En estos casos, es preferible un patrón recursivo setTimeout
:
(function loop() {
setTimeout(function () {
// Escriba su lógica aquí
loop();
}, delay);
})();
En el fragmento de código que hay sobre estas líneas, se declara una función con nombre loop()
y se ejecuta inmediatamente. loop
es llamada recursivamente dentro de setTimeout
después de que la lógica haya sido completamente ejecutada. Aunque este patrón no garantiza la ejecución en un intervalo fijo, si garantiza que el intervalo anterior se haya ejecutado por completo antes de recursar.
Especificaciones
Specification |
---|
HTML Standard # dom-setinterval-dev |
Compatibilidad con navegadores
BCD tables only load in the browser