Existe-t-il un moyen d'appeler périodiquement une fonction en JavaScript?

Réponses:

214

Vous voulez setInterval():

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

Le premier paramètre de setInterval () peut également être une chaîne de code à évaluer.

Vous pouvez effacer une fonction périodique avec:

clearInterval(intervalID);
zombat
la source
15
J'ai voté pour et j'ai décidé d'annuler mon vote pour (mais pas contre) parce que vous utilisez un argument de chaîne pour setInterval. Les fonctions doivent presque toujours être utilisées en faveur d'un argument de chaîne, pour l'efficacité, la sécurité et pour leurs fonctionnalités de fermeture.
Jason S
5
Ça va, ça ne me dérange pas. setInterval()est la bonne réponse à la question, quel que soit le paramètre. Ce n'est qu'un exemple, et les deux méthodes sont par définition correctes.
zombat
2
Je suis d'accord avec Jason S; ça devrait vraiment être une fonction. Dans votre exemple, le seul problème est une perte de performance négligeable, mais c'est une mauvaise habitude à prendre.
Matthew Crumley
4
Je suis d'accord avec vous deux, il est préférable d'utiliser une fonction. Je n'ai jamais dit que non. C'est correct dans tous les cas, mais pour les commentaires, je modifierai la réponse pour qu'elle contienne une fonction à la place.
zombat
37

Veuillez noter que setInterval () n'est souvent pas la meilleure solution pour une exécution périodique - Cela dépend vraiment du javascript que vous appelez régulièrement.

par exemple. Si vous utilisez setInterval () avec une période de 1000 ms et que dans la fonction périodique vous effectuez un appel ajax qui prend parfois 2 secondes pour revenir, vous effectuerez un autre appel ajax avant que la première réponse ne revienne. Ceci n'est généralement pas souhaitable.

De nombreuses bibliothèques ont des méthodes périodiques qui protègent contre les pièges de l'utilisation naïve de setInterval comme l'exemple Prototype donné par Nelson.

Pour obtenir une exécution périodique plus robuste avec une fonction qui contient un appel jQuery ajax, considérez quelque chose comme ceci:

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

Une autre approche consiste à utiliser setTimeout mais à suivre le temps écoulé dans une variable, puis à définir le délai d'expiration à chaque appel de manière dynamique pour exécuter une fonction aussi près que possible de l'intervalle souhaité, mais jamais plus rapidement que vous ne pouvez obtenir des réponses.

Matt Coubrough
la source
setTimeout (myPeriodicMethod, 1000); est appelé 2 fois. est-ce nécessaire? Je pense que le délai d'
attente
1
Oui, le deuxième setTimeout () n'est pas une exigence, vous pouvez simplement appeler myPeriodicMethod () qui effectuerait le premier appel ajax immédiatement ... mais si vous voulez le planifier avec un délai à partir du tout premier appel, vous pouvez l'écrire comme J'ai écrit.
Matt Coubrough
16

Tout le monde a déjà une solution setTimeout / setInterval. Je pense qu'il est important de noter que vous pouvez passer des fonctions à setInterval, pas seulement des chaînes. Il est en fait probablement un peu "plus sûr" de passer des fonctions réelles au lieu de chaînes qui seront "évaluées" à ces fonctions.

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

Ou:

// example 2
var counter = 0;
var interval = setInterval(function() { alert("#"+counter++); }, 5000);
gnarf
la source
3
+1 Si vous êtes un étudiant de l' école Crockford de JavaScript , vous évitez l'évaluation sous toutes ses formes perverses.
Patrick McElhaney
@Patrick - Je ne pense pas que la suggestion "Ne pas utiliser $ (signe dollar) ou \ (barre oblique inverse) dans les noms" conviendra bien avec le lot jQuery :)
Russ Cam
6

Ancienne question mais .. J'avais aussi besoin d'un lanceur de tâches périodique et j'ai écrit TaskTimer . Ceci est également utile lorsque vous devez exécuter plusieurs tâches à des intervalles différents.

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

TaskTimerfonctionne à la fois dans le navigateur et Node. Voir la documentation pour toutes les fonctionnalités.

Onur Yıldırım
la source
3

oui - jetez un œil à setIntervaletsetTimeout pour exécuter du code à certains moments. setInterval serait celui à utiliser pour exécuter du code périodiquement.

Voir une démo et répondre ici pour l'utilisation

Russ Cam
la source
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
la source
1

Puisque vous voulez que la fonction soit exécutée périodiquement , utilisez setInterval

CMS
la source
1

La manière native est en effet setInterval()/ clearInterval(), mais si vous utilisez déjà la bibliothèque Prototype , vous pouvez profiter de PeriodicalExecutor:

new PeriodicalUpdator(myEvent, seconds);

Cela empêche les appels qui se chevauchent. De http://www.prototypejs.org/api/periodicalExecuter :

"il vous protège contre de multiples exécutions parallèles de la fonction de rappel, si elle prend plus de temps que l'intervalle donné pour s'exécuter (il maintient un indicateur interne« en cours d'exécution », qui est protégé contre les exceptions dans la fonction de rappel). Ceci est particulièrement utile si vous utilisez-en un pour interagir avec l'utilisateur à des intervalles donnés (par exemple, utilisez une invite ou confirmez l'appel): cela évitera que plusieurs boîtes de messages n'attendent toutes pour être traitées. "

Nelson
la source