setInterval()
=============

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
--------


```js
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 determina `delay`, estando éste en milisegundos. La primera ejecución ocurre tras el tiempo determinado por `delay`.

`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 de `eval()` 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()`


```js
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


```html
<div id="my\_box">
  <h3>Hello World</h3>
</div>
<button id="start">Start</button>
<button id="stop">Stop</button>
```


#### CSS


```css
.go {
  color: green;
}
.stop {
  color: red;
}
```


#### JavaScript


```js
// 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:


```js
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` :


```js
(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 with JavaScript enabled. Enable JavaScript to view data.

Véase también
-------------

* Polyfill de `setInterval` que permite pasar argumentos al callback en `core-js`
* `setTimeout`
* `clearTimeout`
* `clearInterval`
* `window.requestAnimationFrame`