Esiste un modo per chiamare periodicamente una funzione in JavaScript?


Risposte:


214

Tu vuoi setInterval():

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

Il primo parametro per setInterval () può anche essere una stringa di codice da valutare.

È possibile cancellare una funzione periodica con:

clearInterval(intervalID);

15
Ho votato e poi ho deciso di annullare il mio voto (ma non il voto negativo) perché stai usando un argomento stringa per impostareInterval. Le funzioni dovrebbero quasi sempre essere usate a favore di un argomento stringa, per efficienza, sicurezza e per le loro caratteristiche di chiusura.
Jason S,

5
Va bene, non mi dispiace. setInterval()è la risposta corretta alla domanda, indipendentemente dal parametro. È solo un esempio ed entrambi i metodi sono per definizione corretti.
zombat,

2
Sono d'accordo con Jason S; dovrebbe davvero essere una funzione. Nel tuo esempio, l'unico problema è una perdita di prestazioni trascurabile, ma è una cattiva abitudine da prendere.
Matthew Crumley,

4
Sono d'accordo con entrambi, usare una funzione è meglio. Non ho mai detto di no. È corretto in entrambi i casi, ma per il bene dei commenti, modificherò la risposta per contenere una funzione.
zombat,

37

Nota che setInterval () spesso non è la soluzione migliore per l'esecuzione periodica - Dipende davvero da quale javascript stai chiamando periodicamente.

per esempio. Se si utilizza setInterval () con un periodo di 1000 ms e nella funzione periodica si effettua una chiamata ajax che a volte impiega 2 secondi per tornare, si effettuerà un'altra chiamata ajax prima che la prima risposta torni. Questo è generalmente indesiderabile.

Molte librerie hanno metodi periodici che proteggono dalle insidie ​​dell'uso di setInterval in modo ingenuo come l'esempio Prototype fornito da Nelson.

Per ottenere un'esecuzione periodica più solida con una funzione che contiene una chiamata ajax jQuery, prendere in considerazione qualcosa del genere:

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

Un altro approccio consiste nell'utilizzare setTimeout ma tenere traccia del tempo trascorso in una variabile e quindi impostare il ritardo di timeout su ciascuna chiamata in modo dinamico per eseguire una funzione il più vicino possibile all'intervallo desiderato, ma mai più velocemente di quanto si possano ottenere risposte.


setTimeout (myPeriodicMethod, 1000); viene chiamato 2 volte. è richiesto? Penso che il timeout impostato debba essere chiamato solo nella funzione completa
Vishnudev K,

1
Sì, il secondo setTimeout () non è un requisito, potresti semplicemente chiamare myPeriodicMethod () che eseguirà immediatamente la prima chiamata ajax ... ma se vuoi programmarlo con un ritardo dalla prima chiamata potresti scriverlo come Ho scritto.
Matt Coubrough,

16

Tutti hanno già una soluzione setTimeout / setInterval. Penso che sia importante notare che è possibile passare le funzioni a setInterval, non solo alle stringhe. In realtà è probabilmente un po 'più "sicuro" passare funzioni reali anziché stringhe che verranno "valutate" a tali funzioni.

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

O:

// example 2
var counter = 0;
var interval = setInterval(function() { alert("#"+counter++); }, 5000);

3
+1 Se sei uno studente della scuola Crockford di JavaScript , eviti l'eval in tutte le sue forme malvagie.
Patrick McElhaney,

@Patrick - Non credo che il suggerimento "Non usare $ (segno di dollaro) o \ (barra rovesciata) nei nomi" scenderà bene con il lotto jQuery :)
Russ Cam

6

Vecchia domanda ma ... Avevo anche bisogno di un runner periodico e ho scritto TaskTimer . Ciò è utile anche quando è necessario eseguire più attività su intervalli diversi.

// 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();

TaskTimerfunziona sia nel browser che nel nodo. Vedi la documentazione per tutte le funzioni.




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);
}

1

Poiché si desidera che la funzione venga eseguita periodicamente , utilizzare setInterval


1

Il modo nativo è effettivamente setInterval()/ clearInterval(), ma se stai già utilizzando la libreria Prototype puoi usufruire di PeriodicalExecutor:

new PeriodicalUpdator(myEvent, seconds);

Questo impedisce chiamate sovrapposte. Da http://www.prototypejs.org/api/periodicalExecuter :

"ti protegge da più esecuzioni parallele della funzione di callback, nel caso in cui occorra più tempo dell'intervallo dato (mantiene un flag" in esecuzione "interno, che è protetto dalle eccezioni nella funzione di callback). Ciò è particolarmente utile se utilizzane uno per interagire con l'utente a determinati intervalli (ad es. usa un prompt o conferma la chiamata): questo eviterà più finestre di messaggio tutte in attesa di essere attivate. "

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.