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
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.
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.
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:
setInterval
peut facilement être adapté par substitutionclearInterval()
plus tardExemple:
// 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.
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.
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);
// 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);
Je suggérerai d'appeler les fonctions dans l'ordre suivant
var _timer = setInterval(foo, delay, params);
foo(params)
Vous pouvez aussi passer le_timer
au foo, si vous voulez clearInterval(_timer)
à certaines conditions
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
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.
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 );
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);