Antworten:
Es ist am einfachsten, die Funktion beim ersten Mal direkt selbst aufzurufen:
foo();
setInterval(foo, delay);
Es gibt jedoch gute Gründe, dies zu vermeiden setInterval
- insbesondere unter bestimmten Umständen kann eine ganze Reihe von setInterval
Ereignissen ohne Verzögerung unmittelbar nacheinander eintreffen. Ein weiterer Grund ist, dass Sie, wenn Sie die Schleife stoppen möchten, explizit aufrufen müssen, clearInterval
was bedeutet, dass Sie sich an das vom ursprünglichen setInterval
Aufruf zurückgegebene Handle erinnern müssen .
Eine alternative Methode besteht darin, foo
sich für nachfolgende Aufrufe auszulösen, indem Sie setTimeout
stattdessen Folgendes verwenden :
function foo() {
// do stuff
// ...
// and schedule a repeat
setTimeout(foo, delay);
}
// start the cycle
foo();
Dies garantiert, dass zwischen den Anrufen mindestens ein Intervall liegt delay
. Es macht es auch einfacher, die Schleife bei Bedarf abzubrechen - Sie rufen nur nicht an, setTimeout
wenn Ihre Schleifenbeendigungsbedingung erreicht ist.
Besser noch, Sie können das alles in einem sofort aufgerufenen Funktionsausdruck zusammenfassen, der die Funktion erstellt, die sich dann wie oben wieder aufruft und automatisch die Schleife startet:
(function foo() {
...
setTimeout(foo, delay);
})();
Dies definiert die Funktion und startet den Zyklus auf einmal.
setTimeout
?
setInterval
Ereignissen ohne Verzögerung unmittelbar nacheinander eintreffen.
setTimeout
Methode verwende?
Ich bin mir nicht sicher, ob ich dich richtig verstehe, aber du könntest leicht so etwas tun:
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
Es gibt offensichtlich eine Reihe von Möglichkeiten, dies zu tun, aber das ist die prägnanteste Art, die ich mir vorstellen kann.
arguments.callee
ist nicht im strengen ES5-Modus verfügbar
Ich bin aufgrund des gleichen Problems auf diese Frage gestoßen, aber keine der Antworten hilft, wenn Sie sich genau so verhalten müssen,setInterval()
aber mit dem einzigen Unterschied, dass die Funktion sofort am Anfang aufgerufen wird.
Hier ist meine Lösung für dieses Problem:
function setIntervalImmediately(func, interval) {
func();
return setInterval(func, interval);
}
Der Vorteil dieser Lösung:
setInterval
kann einfach durch Ersetzen angepasst werdenclearInterval()
später weitergebenBeispiel:
// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
console.log('hello');
}, 1000);
// clear interval after 4.5 seconds
setTimeout( _ => {
clearInterval(myInterval);
}, 4500);
Um frech zu sein, wenn Sie wirklich brauchen, setInterval
dann können Sie auch das Original ersetzen setInterval
. Daher ist keine Änderung des Codes erforderlich, wenn Sie diesen vor Ihrem vorhandenen Code hinzufügen:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
Alle oben aufgeführten Vorteile gelten hier, es ist jedoch keine Substitution erforderlich.
setTimeout
Lösung, da sie ein setInterval
Objekt zurückgibt . Um zu vermeiden, dass Funktionen aufgerufen werden, die möglicherweise später im Code enthalten sind und daher zum aktuellen Zeitpunkt nicht definiert sind, verpacke ich den ersten Funktionsaufruf in eine setTimeout
Funktion wie diese: setTimeout(function(){ func();},0);
Die erste Funktion wird dann nach dem aktuellen Verarbeitungszyklus aufgerufen, der ebenfalls sofort erfolgt , dies aber ist mehr Fehler bewiesen.
Sie können setInterval()
eine Funktion einschließen , die dieses Verhalten bereitstellt:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
... dann benutze es so:
instantGratification( function() {
console.log( 'invoked' );
}, 3000);
Hier ist ein Wrapper, um es hübsch zu machen, wenn Sie es brauchen:
(function() {
var originalSetInterval = window.setInterval;
window.setInterval = function(fn, delay, runImmediately) {
if(runImmediately) fn();
return originalSetInterval(fn, delay);
};
})();
Setzen Sie das dritte Argument von setInterval auf true und es wird unmittelbar nach dem Aufruf von setInterval zum ersten Mal ausgeführt:
setInterval(function() { console.log("hello world"); }, 5000, true);
Oder lassen Sie das dritte Argument weg und es behält sein ursprüngliches Verhalten bei:
setInterval(function() { console.log("hello world"); }, 5000);
Einige Browser unterstützen zusätzliche Argumente für setInterval, die dieser Wrapper nicht berücksichtigt. Ich denke, diese werden selten verwendet, aber denken Sie daran, wenn Sie sie brauchen.
Denn jemand muss das Äußere nach this
innen bringen, als wäre es eine Pfeilfunktion.
(function f() {
this.emit("...");
setTimeout(f.bind(this), 1000);
}).bind(this)();
Wenn Sie der oben genannte Müll stört, können Sie stattdessen eine Schließung vornehmen.
(that => {
(function f() {
that.emit("...");
setTimeout(f, 1000);
})();
})(this);
Oder verwenden Sie den @autobind
Dekorator je nach Code.
Ich werde vorschlagen, die Funktionen in der folgenden Reihenfolge aufzurufen
var _timer = setInterval(foo, delay, params);
foo(params)
Sie können das auch _timer
an das foo weitergeben, wenn Sie clearInterval(_timer)
unter einer bestimmten Bedingung möchten
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
Hier ist eine einfache Version für Anfänger, ohne herumzuspielen. Es deklariert nur die Funktion, ruft sie auf und startet dann das Intervall. Das ist es.
//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 );
Es gibt ein praktisches npm-Paket namens firstInterval (vollständige Offenlegung, es ist meins).
Viele der Beispiele hier enthalten keine Parameterbehandlung, und das Ändern des Standardverhaltens setInterval
in einem großen Projekt ist böse. Aus den Dokumenten:
Dieses Muster
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
ist identisch mit
firstInterval(callback, 1000, p1, p2);
Wenn Sie im Browser altmodisch sind und die Abhängigkeit nicht möchten, können Sie sie einfach aus dem Code ausschneiden und einfügen.
// 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);
Ok, das ist so komplex, also lassen Sie es mich einfacher sagen:
function hello(status ) {
console.log('world', ++status.count);
return status;
}
setInterval(hello, 5 * 1000, hello({ count: 0 }));
Sie können eine sehr kleine anfängliche Verzögerungszeit (z. B. 100) einstellen und diese innerhalb der Funktion auf die gewünschte Verzögerungszeit einstellen:
var delay = 100;
function foo() {
console.log("Change initial delay-time to what you want.");
delay = 12000;
setTimeout(foo, delay);
}
Es gibt ein Problem mit dem sofortigen asynchronen Aufruf Ihrer Funktion, da standardmäßig setTimeout / setInterval ein minimales Zeitlimit von einigen Millisekunden aufweist, selbst wenn Sie es direkt auf 0 setzen. Dies wird durch eine browserspezifische Arbeit verursacht.
Ein Beispiel für Code mit einer REALEN Verzögerung von Null, der in Chrome, Safari und Opera funktioniert
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
Weitere Informationen finden Sie hier
Und nach dem ersten Handaufruf können Sie mit Ihrer Funktion ein Intervall erstellen.
eigentlich ist das am schnellsten zu tun
interval = setInterval(myFunction(),45000)
Dies ruft meine Funktion auf und führt sie dann alle 45 Sekunden erneut aus, was sich von der Ausführung unterscheidet
interval = setInterval(myfunction, 45000)
das wird es nicht nennen, sondern nur planen
myFunction()
es sich selbst zurückgibt. Stattdessen setInterval
ist es besser, jede Funktion, die von ihr aufgerufen werden soll, so zu ändern, dass sie setInterval
einmal umbrochen wird, wie es die anderen Antworten vorschlagen.
function
einmalsetInterval()