SetTimeout y setInterval en JavaScript programan callbacks para más adelante. SetTimeout solicita una ejecución después de un retraso; setInterval repite la programación a intervalos. Ambos devuelven un identificador que permite cancelar el temporizador.
No garantizan una hora exacta. El navegador puede retrasar la ejecución por otras tareas, ahorro de recursos o porque la pestaña está en segundo plano.
Ejecutar una función una vez con setTimeout
const id = setTimeout(() => {
console.log("Han transcurrido al menos unos dos segundos.");
}, 2000);
// Si necesitas cancelarlo antes:
// clearTimeout(id);El retraso se expresa en milisegundos. Pasa una función, no un texto de código. Evita también llamar la función directamente al programarla, salvo que de verdad quieras utilizar su resultado como callback.
Ejemplo completo con iniciar y detener
<button type="button" id="iniciar">Iniciar contador</button>
<button type="button" id="detener">Detener</button>
<p id="contador">0</p>
<script>
const salida = document.querySelector("#contador");
let intervalo = null;
let numero = 0;
document.querySelector("#iniciar").addEventListener("click", () => {
if (intervalo !== null) return;
intervalo = setInterval(() => {
numero += 1;
salida.textContent = String(numero);
}, 1000);
});
document.querySelector("#detener").addEventListener("click", () => {
clearInterval(intervalo);
intervalo = null;
});
</script>La comprobación inicial evita crear varios intervalos al pulsar repetidamente. El contador registra callbacks ejecutados: no es un reloj preciso de segundos reales.
Cómo medir tiempo transcurrido
Para una duración durante la vida de una página, guarda un punto inicial con performance.now y calcula la diferencia al actualizar. Si necesitas que una cuenta atrás resista recargas, suspensión o sincronización con un servidor, define además una referencia temporal adecuada a esa necesidad.
En una cuenta atrás, conserva el objetivo y vuelve a calcular cuánto falta; no restes un segundo suponiendo que cada callback se ejecutará puntualmente.
Evitar peticiones que se solapan
Un setInterval no espera a que termine una operación asíncrona. Si una petición tarda más que el intervalo, pueden acumularse varias. Una alternativa es programar la siguiente ejecución cuando termina la anterior:
let detenido = false;
let temporizador;
async function ciclo() {
try {
await tareaAsincrona(); // Define esta función en tu aplicación
} catch (error) {
console.error(error);
} finally {
if (!detenido) temporizador = setTimeout(ciclo, 5000);
}
}
function detenerCiclo() {
detenido = true;
clearTimeout(temporizador);
}
// Llama a ciclo() solo después de definir tareaAsincrona.Este fragmento es un patrón para integrar, no una petición completa. Su espera comienza tras terminar la tarea. Detener el ciclo evita nuevas ejecuciones, pero no cancela automáticamente una petición ya iniciada; para eso necesitas su mecanismo de cancelación.
SetTimeout con cero no es inmediato
Un retraso cero solicita ejecutar el callback en una oportunidad posterior del bucle de eventos, después de que el código actual permita continuar. No interrumpe la función que se está ejecutando.
Errores frecuentes
- No conservar el identificador para cancelar.
- Acumular temporizadores cada vez que se abre una vista.
- Usar intervalos como reloj preciso.
- Programar código como cadena en lugar de una función.
Preguntas frecuentes
¿Debo limpiar los temporizadores de un componente?
Sí, cuando dejan de ser necesarios. En aplicaciones con componentes, utiliza el mecanismo de limpieza de su ciclo de vida.
¿Sirven para animar cada fotograma?
Para actualizaciones visuales ligadas a los fotogramas, estudia requestAnimationFrame en lugar de asumir que un intervalo sincroniza con la pantalla.
Para conectar los botones del ejemplo, repasa la guía del DOM.
Referencia técnica: documentación de MDN.




