web-dev-qa-db-fra.com

Exécuter la fonction setInterval sans délai la première fois

Il existe un moyen de configurer la méthode setInterval de javascript pour exécuter la méthode immédiatement puis s'exécuter avec le minuteur

254
Jorge

Il est plus simple d'appeler la fonction directement la première fois:

foo();
setInterval(foo, delay);

Cependant, il y a de bonnes raisons d'éviter setInterval - en particulier dans certaines circonstances, une foule d'événements setInterval peut arriver immédiatement l'un après l'autre sans délai. Une autre raison est que si vous souhaitez arrêter la boucle, vous devez explicitement appeler clearInterval, ce qui signifie que vous devez vous rappeler le descripteur renvoyé par l'appel setInterval d'origine.

Donc, une autre méthode consiste à laisser foo se déclencher pour les appels suivants en utilisant setTimeout à la place:

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

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

// start the cycle
foo();

Cela garantit qu'il y a au moins un intervalle de delay entre les appels. Cela facilite également l'annulation de la boucle si nécessaire - vous n'appelez simplement pas setTimeout lorsque votre condition de fin de boucle est atteinte.

Mieux encore, vous pouvez envelopper tout cela dans une expression de fonction immédiatement invoquée qui crée la fonction, qui s'appelle ensuite comme ci-dessus et lance automatiquement la boucle:

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

qui définit la fonction et lance le cycle en une fois.

412
Alnitak

Je ne suis pas sûr de bien vous comprendre, mais vous pouvez facilement faire quelque chose comme ceci:

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

Il y a évidemment plusieurs façons de le faire, mais c'est la façon la plus concise à laquelle je puisse penser.

169
chjj

Je suis tombé sur cette question en raison du même problème, mais aucune des réponses n’est utile si vous devez vous comporter exactement comme comme setInterval() mais avec la différence seulement que la fonction est appelée immédiatement au début.

Voici ma solution à ce problème:

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

L'avantage de cette solution:

  • le code existant en utilisant setInterval peut facilement être adapté par substitution
  • fonctionne en mode strict
  • cela fonctionne avec les fonctions nommées et les fermetures existantes
  • vous pouvez toujours utiliser la valeur de retour et la transmettre à clearInterval() plus tard

Exemple:

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

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

Pour être effronté, si vous devez vraiment utiliser setInterval, vous pouvez également remplacer l'original setInterval. Par conséquent, aucun changement de code n'est requis lorsque vous ajoutez ceci avant votre code existant:

var setIntervalOrig = setInterval;

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

Tous les avantages énumérés ci-dessus s’appliquent ici, mais aucune substitution n’est nécessaire.

8
Jens Wirth

Voici un emballage pour y remédier si vous en avez besoin:

(function() {
    var originalSetInterval = window.setInterval;

    window.setInterval = function(fn, delay, runImmediately) {
        if(runImmediately) fn();
        return originalSetInterval(fn, delay);
    };
})();

Définissez le troisième argument de setInterval sur true et il s'exécutera pour la première fois immédiatement après l'appel de setInterval:

setInterval(function() { console.log("hello world"); }, 5000, true);

Ou omettez le troisième argument et il conservera son comportement d'origine:

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

Certains navigateurs supportent des arguments supplémentaires pour setInterval que ce gestionnaire ne prend pas en compte; Je pense que ceux-ci sont rarement utilisés, mais gardez cela à l'esprit si vous en avez besoin.

7
Mahn

Vous pouvez envelopper setInterval() dans une fonction fournissant ce comportement:

function instantGratification( fn, delay ) {
    fn();
    setInterval( fn, delay );
}

... puis utilisez-le comme ceci:

instantGratification( function() {
    console.log( 'invoked' );
}, 3000);
5
user113716

// YCombinator
function anonymous(fnc) {
  return function() {
    fnc.apply(fnc, arguments);
    return fnc;
  }
}

// Invoking the first time:
setInterval(anonymous(function() {
  console.log("bar");
})(), 4000);

// Not invoking the first time:
setInterval(anonymous(function() {
  console.log("foo");
}), 4000);
// Or simple:
setInterval(function() {
  console.log("baz");
}, 4000);

1
NSD

Je suggérerai d'appeler les fonctions dans l'ordre suivant

var _timer = setInterval(foo, delay, params);
foo(params)

Vous pouvez aussi passer le_timerau foo, si vous voulez clearInterval(_timer) à certaines conditions

var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
1
Jayant Varshney

Pour que quelqu'un ait besoin de placer la this extérieure à l'intérieur comme s'il s'agissait d'une fonction de flèche.

(function f() {
    this.emit("...");
    setTimeout(f.bind(this), 1000);
}).bind(this)();

Si les déchets qui précèdent vous dérangent, vous pouvez effectuer une fermeture.

(that => {
    (function f() {
        that.emit("...");
        setTimeout(f, 1000);
    })();
})(this);

Vous pouvez aussi utiliser le décorateur @autobind en fonction de votre code.

Il existe un paquet npm pratique appelé firstInterval (divulgation complète, c'est le mien).

La plupart des exemples ici n'incluent pas la gestion des paramètres et il est pervers de modifier les comportements par défaut de setInterval dans tout grand projet. De la docs:

Ce modèle

setInterval(callback, 1000, p1, p2);
callback(p1, p2);

est identique à

firstInterval(callback, 1000, p1, p2);

Si vous êtes une vieille école dans le navigateur et que vous ne voulez pas la dépendance, c’est un copier-coller facile à partir de le code.

0
jimm101

Voici une version simple pour les novices sans tous les déconner. Il déclare simplement la fonction, l'appelle, puis commence l'intervalle. C'est tout.

//Declare your function here
function My_Function(){
  console.log("foo");
}    

//Call the function first
My_Function();

//Set the interval
var interval = window.setInterval( My_Function, 500 );
0
Polyducks

Pour résoudre ce problème, je lance la fonction une première fois après le chargement de la page.

function foo(){ ... }

window.onload = function() {
   foo();
};

window.setInterval(function()
{
    foo(); 
}, 5000);
0
user4989618