Exécuter la fonction setInterval sans délai la première fois
il y a une façon de configurer la méthode setInterval
de javascript pour exécuter la méthode immédiatement, puis exécute avec le timer
12 réponses
il est plus simple de simplement appeler la fonction vous-même 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 charge entière de setInterval
événements peuvent arriver immédiatement après l'autre sans aucun retard. Une autre raison est que si vous voulez arrêter la boucle vous devez appeler explicitement clearInterval
ce qui signifie que vous devez vous rappeler la poignée retournée de l'original setInterval
appel.
donc une méthode alternative est d'avoir foo
déclenchement lui - même 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. Il est également plus facile d'annuler la boucle si nécessaire - il suffit de ne pas appeler setTimeout
lorsque votre condition de terminaison de boucle est atteinte.
mieux pourtant, vous pouvez envelopper tout cela dans une expression de fonction immédiatement invoquée qui crée la fonction, qui s'appelle ensuite à nouveau comme ci-dessus, et démarre automatiquement la boucle:
(function foo() {
...
setTimeout(foo, delay);
})();
qui définit la fonction et démarre le cycle d'un seul coup.
Je ne suis pas sûr de vous comprendre correctement, mais vous pourriez facilement faire quelque chose comme ça:
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 que je puisse imaginer.
Voici un wrapper pour la jolie-fy si vous en avez besoin:
(function() {
var originalSetInterval = window.setInterval;
window.setInterval = function(fn, delay, runImmediately) {
if(runImmediately) fn();
return originalSetInterval(fn, delay);
};
})();
définit le troisième argument de setInterval à true et il sera exécuté pour la première fois immédiatement après avoir appelé setInterval:
setInterval(function() { console.log("hello world"); }, 5000, true);
ou omettre le troisième argument et il conservera son comportement original:
setInterval(function() { console.log("hello world"); }, 5000);
certains navigateurs prennent en charge arguments supplémentaires pour setInterval que ce wrapper ne prend pas je pense qu'ils sont rarement utilisés, mais gardez cela à l'esprit si vous en avez besoin.
je suis tombé sur cette question en raison du même problème, mais aucune des réponses n'aide si vous avez besoin de se comporter exactement comme setInterval()
mais avec la seulement différence 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:
- code existant utilisant
setInterval
peut facilement être adapté par substitution - fonctionne en mode strict
- il fonctionne avec des fonctions nommées et des fermetures existantes
- vous pouvez toujours utiliser la valeur de retour et la passer à
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 insolent, si vous avez vraiment besoin d'utiliser setInterval
alors vous pouvez aussi remplacer l'original setInterval
. Par conséquent, aucun changement du code requis pour ajouter ce code avant votre code existant:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
pourtant, tous les avantages énumérés ci-dessus s'appliquent ici, mais aucune substitution n'est nécessaire.
vous pourriez envelopper setInterval()
dans une fonction qui fournit ce comportement:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
...alors 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 la séquence suivante
var _timer = setInterval(foo, delay, params);
foo(params)
vous pouvez également passer le _timer
à la foo, si vous voulez clearInterval(_timer)
à une certaine condition
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
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);
il y a un paquet npm pratique appelé first interval (divulgation complète, c'est à moi).
beaucoup des exemples ici n'incluent pas la gestion des paramètres, et changer les comportements par défaut de setInterval
dans n'importe quel grand projet est mauvais. Extrait du docs:
Ce modèle
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
est identique à
firstInterval(callback, 1000, p1, p2);
si vous êtes de la vieille école dans le navigateur et ne voulez pas la dépendance, c'est un coup-et-coller facile de le code.
Voici une version simple pour les novices sans déconner. Il déclare simplement la fonction, les appels, 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 );
il y a un problème avec l'appel asynchrone immédiat de votre fonction, parce que le standard setTimeout/setInterval a un délai minimal d'environ plusieurs millisecondes, même si vous le définissez directement à 0. Il est causé par un travail spécifique au navigateur.
un exemple de code avec un vrai délai zéro qui fonctionne en Chrome, Safari, Opéra
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
vous pouvez trouver plus d'information ici
et après le premier appel manuel vous pouvez créer un intervalle avec votre fonction.
en fait, le plus rapide est de faire
interval = setInterval(myFunction(),45000)
cela va appeler myfunction, et puis le faire à nouveau toutes les 45 secondes ce qui est différent de faire
interval = setInterval(myfunction, 45000)
qui ne l'appellera pas, mais programmez-le seulement