web-dev-qa-db-fra.com

Javascript setInterval ne fonctionne pas

J'ai besoin d'exécuter une fonction javascript toutes les 10 secondes.

Je comprends que la syntaxe doit fonctionner comme suit mais je n'obtiens aucun succès:

function funcName() {
    alert("test");
}

var func = funcName();
var run = setInterval("func",10000)

Mais cela ne fonctionne pas. De l'aide?

25
mauzilla

Beaucoup d'autres réponses se concentrent sur un modèle qui fonctionne, mais leurs explications ne sont pas vraiment très détaillées quant à la raison pour laquelle votre code actuel ne fonctionne pas.

Votre code, pour référence:

function funcName() {
    alert("test");
}

var func = funcName();
var run = setInterval("func",10000)

Décomposons cela en morceaux. Votre fonction funcName est très bien. Notez que lorsque vous appelez funcName (en d'autres termes, vous l'exécutez), vous alerterez "test". Mais notez que funcName() - les parenthèses signifient "appeler" ou "exécuter" la fonction - ne retourne pas réellement de valeur. Lorsqu'une fonction n'a pas de valeur de retour, elle prend par défaut une valeur appelée undefined.

Lorsque vous appelez une fonction, vous ajoutez sa liste d'arguments à la fin entre parenthèses. Lorsque vous n'avez aucun argument pour passer la fonction, vous ajoutez simplement des parenthèses vides, comme funcName(). Mais lorsque vous voulez faire référence à la fonction elle-même et ne pas l'appeler, vous n'avez pas besoin des parenthèses car les parenthèses indiquent de l'exécuter.

Donc, quand vous dites:

var func = funcName();

Vous déclarez en fait une variable func qui a une valeur de funcName(). Mais remarquez les parenthèses. funcName() est en fait la valeur de retour de funcName. Comme je l'ai dit ci-dessus, étant donné que funcName ne renvoie aucune valeur, il s'agit par défaut de undefined. En d'autres termes, votre variable func aura en fait la valeur undefined.

Ensuite, vous avez cette ligne:

var run = setInterval("func",10000)

La fonction setInterval prend deux arguments. La première est la fonction à exécuter de temps en temps, et la seconde est le nombre de millisecondes entre chaque exécution de la fonction.

Cependant, le premier argument devrait vraiment être une fonction, pas une chaîne. S'il s'agit d'une chaîne, le moteur JavaScript utilisera à la place eval sur cette chaîne. En d'autres termes, votre setInterval exécute le code JavaScript suivant:

func
// 10 seconds later....
func
// and so on

Cependant, func n'est qu'une variable (avec la valeur undefined, mais ce n'est pas pertinent). Ainsi, toutes les dix secondes, le moteur JS évalue la variable func et renvoie undefined. Mais cela ne fait vraiment rien. Je veux dire, techniquement, il est évalué toutes les 10 secondes, mais vous n'en verrez aucun effet.

La solution consiste à donner à setInterval une fonction à exécuter à la place d'une chaîne. Donc, dans ce cas:

var run = setInterval(funcName, 10000);

Notez que je ne lui ai pas donné func. C'est parce que func n'est pas pas une fonction dans votre code; c'est la valeur undefined, car vous lui avez attribué funcName(). Comme je l'ai dit ci-dessus, funcName() appellera la fonction funcName et renverra la valeur de retour de la fonction. Étant donné que funcName ne renvoie rien, cette valeur par défaut est undefined. Je sais que je l'ai dit plusieurs fois maintenant, mais c'est vraiment un concept très important: quand vous voyez funcName(), vous devriez penser "la valeur de retour de funcName". Lorsque vous voulez faire référence à une fonction elle-même, comme une entité distincte, vous devez laisser les parenthèses afin de ne pas l'appeler: funcName.

Ainsi, une autre solution pour votre code serait:

var func = funcName;
var run = setInterval(func, 10000);

Cependant, c'est un peu redondant: pourquoi utiliser func au lieu de funcName?

Ou vous pouvez rester aussi fidèle que possible au code d'origine en modifiant deux bits:

var func = funcName;
var run = setInterval("func()", 10000);

Dans ce cas, le moteur JS évaluera func() toutes les dix secondes. En d'autres termes, il alertera "test" Toutes les dix secondes. Cependant, comme le dit la célèbre phrase, eval est mauvais , vous devriez donc essayer de l'éviter autant que possible.

Une autre variante de ce code consiste à utiliser une fonction anonyme. En d'autres termes, une fonction qui n'a pas de nom - vous la déposez simplement dans le code parce que vous ne vous souciez pas de son nom.

setInterval(function () {
    alert("test");
}, 10000);

Dans ce cas, comme je ne me soucie pas du nom de la fonction, je laisse simplement une fonction générique sans nom (anonyme).

108
Reid

Remplacez setInterval("func",10000) par setInterval(funcName, 10000) ou setInterval("funcName()",10000). Le premier est la méthode recommandée.

6
techfoobar

Essaye ça:

function funcName() {
    alert("test");
}

var run = setInterval(funcName, 10000)
4
qwertymk

C'est parce que vous devez passer une fonction, pas une chaîne:

function funcName() {
    alert("test");
}

setInterval(funcName, 10000);

Votre code a deux problèmes:

  • var func = funcName(); appelle immédiatement la fonction et affecte la valeur de retour.
  • Seul "func" N'est pas valide même si vous utilisez la syntaxe de type eval incorrecte et obsolète de setInterval. Ce serait setInterval("func()", 10000) pour appeler la fonction comme un eval.
3
ThiefMaster