¿Hay alguna forma de llamar a una función periódicamente en JavaScript?

Respuestas:

214

Tu quieres setInterval():

var intervalID = setInterval(function(){alert("Interval reached");}, 5000);

El primer parámetro para setInterval () también puede ser una cadena de código para evaluar.

Puede borrar una función periódica con:

clearInterval(intervalID);
zombat
fuente
15
Voté a favor y luego decidí rescindir mi voto a favor (pero no a favor) porque estás usando un argumento de cadena para establecer Intervalo. Las funciones casi siempre se deben utilizar a favor de un argumento de cadena, por eficiencia, seguridad y por sus características de cierre.
Jason S
55
Eso está bien, no me importa. setInterval()es la respuesta correcta a la pregunta, sin importar el parámetro. Es solo un ejemplo, y ambos métodos son, por definición, correctos.
zombat
2
Estoy de acuerdo con Jason S; Realmente debería ser una función. En su ejemplo, el único problema es una pérdida de rendimiento insignificante, pero es un mal hábito.
Matthew Crumley
44
Estoy de acuerdo con ustedes dos, usar una función es mejor. Nunca dije que no lo fuera. Es correcto de cualquier manera, pero por el bien de los comentarios, editaré la respuesta para que contenga una función.
zombat
37

Tenga en cuenta que setInterval () a menudo no es la mejor solución para la ejecución periódica: realmente depende de qué javascript esté llamando periódicamente.

p.ej. Si usa setInterval () con un período de 1000 ms y en la función periódica realiza una llamada ajax que ocasionalmente demora 2 segundos en regresar, realizará otra llamada ajax antes de que vuelva la primera respuesta. Esto generalmente no es deseable.

Muchas bibliotecas tienen métodos periódicos que protegen contra las trampas del uso de setInterval ingenuamente, como el ejemplo de prototipo dado por Nelson.

Para lograr una ejecución periódica más robusta con una función que tenga una llamada jQuery ajax, considere algo como esto:

function myPeriodicMethod() {
  $.ajax({
    url: ..., 
    success: function(data) {
      ...
    },
    complete: function() {
      // schedule the next request *only* when the current one is complete:
      setTimeout(myPeriodicMethod, 1000);
    }
  });
}

// schedule the first invocation:
setTimeout(myPeriodicMethod, 1000);

Otro enfoque es usar setTimeout pero rastrear el tiempo transcurrido en una variable y luego establecer el retraso de tiempo de espera en cada invocación dinámicamente para ejecutar una función lo más cerca posible del intervalo deseado pero nunca más rápido de lo que puede obtener respuestas.

Matt Coubrough
fuente
setTimeout (myPeriodicMethod, 1000); Se llama 2 veces. ¿Se requiere? Creo que el tiempo de espera establecido debería llamarse solo en la función completa
Vishnudev K
1
Sí, el segundo setTimeout () no es un requisito, simplemente puede llamar a myPeriodicMethod () que realizaría la primera llamada ajax inmediatamente ... pero si desea programarlo con un retraso desde la primera llamada, puede escribirlo como He escrito.
Matt Coubrough
16

Todos ya tienen una solución setTimeout / setInterval. Creo que es importante tener en cuenta que puede pasar funciones a setInterval, no solo cadenas. En realidad, es probablemente un poco "más seguro" pasar funciones reales en lugar de cadenas que serán "evadidas" a esas funciones.

// example 1
function test() {
  alert('called');
}
var interval = setInterval(test, 10000);

O:

// example 2
var counter = 0;
var interval = setInterval(function() { alert("#"+counter++); }, 5000);
Gnarf
fuente
3
+1 Si eres un estudiante de la escuela Crockford de JavaScript , evitas evaluar en todas sus formas malvadas.
Patrick McElhaney el
@Patrick - No creo que la sugerencia "No usar $ (signo de dólar) o \ (barra invertida) en los nombres" vaya a funcionar bien con el lote jQuery :)
Russ Cam
6

Antigua pregunta pero ... También necesitaba un corredor de tareas periódicas y escribí TaskTimer . Esto también es útil cuando necesita ejecutar múltiples tareas en diferentes intervalos.

// Timer with 1000ms (1 second) base interval resolution.
var timer = new TaskTimer(1000)

// Add task(s) based on tick intervals.
timer.addTask({
    name: 'job1',       // unique name of the task
    tickInterval: 5,    // run every 5 ticks (5 x interval = 5000 ms)
    totalRuns: 10,      // run 10 times only. (set to 0 for unlimited times)
    callback: function (task) {
        // code to be executed on each run
        console.log(task.name + ' task has run ' + task.currentRuns + ' times.');
    }
});

// Start the timer
timer.start();

TaskTimerFunciona tanto en el navegador como en el nodo. Consulte la documentación para todas las funciones.

Onur Yıldırım
fuente
2
function test() {
 alert('called!');
}
var id = setInterval('test();', 10000); //call test every 10 seconds.
function stop() { // call this to stop your interval.
   clearInterval(id);
}
Ben Lesh
fuente
1

Como desea que la función se ejecute periódicamente , use setInterval

CMS
fuente
1

La forma nativa es de hecho setInterval()/ clearInterval(), pero si ya está utilizando la biblioteca Prototype , puede aprovechar PeriodicalExecutor:

new PeriodicalUpdator(myEvent, seconds);

Esto evita la superposición de llamadas. De http://www.prototypejs.org/api/periodicalExecuter :

"lo protege contra múltiples ejecuciones paralelas de la función de devolución de llamada, en caso de que tarde más que el intervalo dado en ejecutarse (mantiene un indicador interno de" ejecución ", que está protegido contra excepciones en la función de devolución de llamada). Esto es especialmente útil si usted use uno para interactuar con el usuario a intervalos determinados (p. ej., use un aviso o confirme la llamada): esto evitará que varios cuadros de mensajes estén esperando ser procesados ​​".

Nelson
fuente