Ejecute la función setInterval sin demora la primera vez

Resuelto Jorge asked hace 13 años • 18 respuestas

Hay una manera de configurar el setIntervalmétodo de JavaScript para ejecutar el método inmediatamente y luego ejecutar con el temporizador.

Jorge avatar Jul 14 '11 03:07 Jorge
Aceptado

Lo más sencillo es llamar la función usted mismo directamente la primera vez:

foo();
setInterval(foo, delay);

Sin embargo, hay buenas razones para evitarlo setInterval; en particular, en algunas circunstancias, una gran cantidad de setIntervaleventos pueden suceder inmediatamente uno tras otro y sin demora. Otra razón es que si desea detener el bucle, debe llamar explícitamente, clearIntervallo que significa que debe recordar el identificador devuelto por la setIntervalllamada original.

Entonces, un método alternativo es activarse foopara llamadas posteriores usando setTimeouten su lugar:

function foo() {
   // do stuff
   // ...

   // and schedule a repeat
   setTimeout(foo, delay);
}

// start the cycle
foo();

Esto garantiza que haya al menos un intervalo de delayentre llamadas. También hace que sea más fácil cancelar el bucle si es necesario: simplemente no llama setTimeoutcuando se alcanza la condición de terminación del bucle.

Mejor aún, puedes resumir todo eso en una expresión de función invocada inmediatamente que crea la función, que luego se llama a sí misma nuevamente como se indicó anteriormente y automáticamente inicia el ciclo:

(function foo() {
    ...
    setTimeout(foo, delay);
})();

que define la función e inicia el ciclo de una sola vez.

Alnitak avatar Jul 13 '2011 20:07 Alnitak

No estoy seguro de haberte entendido correctamente, pero fácilmente podrías hacer algo como esto:

setInterval(function hello() {
  console.log('world');
  return hello;
}(), 5000);

Obviamente hay varias formas de hacer esto, pero esa es la forma más concisa que se me ocurre.

chjj avatar Jul 13 '2011 20:07 chjj

Me topé con esta pregunta debido al mismo problema, pero ninguna de las respuestas ayuda si necesitas comportarte exactamente como setInterval(), pero con la única diferencia de que la función se llama inmediatamente al principio.

Aquí está mi solución a este problema:

function setIntervalImmediately(func, interval) {
  func();
  return setInterval(func, interval);
}

La ventaja de esta solución:

  • El uso del código existente setIntervalse puede adaptar fácilmente mediante sustitución.
  • funciona en modo estricto
  • Funciona con funciones y cierres con nombre existentes.
  • aún puedes usar el valor de retorno y pasarlo clearInterval()más tarde

Ejemplo:

// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
        console.log('hello');
    }, 1000);

// clear interval after 4.5 seconds
setTimeout( _ => {
        clearInterval(myInterval);
    }, 4500);

Para ser descarado, si realmente necesitas usarlo setInterval, también puedes reemplazar el original setInterval. Por lo tanto, no se requiere ningún cambio de código al agregar esto antes del código existente:

var setIntervalOrig = setInterval;

setInterval = function(func, interval) {
    func();
    return setIntervalOrig(func, interval);
}

Aún así, todas las ventajas enumeradas anteriormente se aplican aquí, pero no es necesaria ninguna sustitución.

Jens Wirth avatar Apr 13 '2016 08:04 Jens Wirth