Wenn Sie mit der clientseitigen JavaScript-Programmierung vertraut sind, haben Sie möglicherweise die SetTimeOut- und SetInterval-Funktionen verwendet, die Verzögerungen für einen bestimmten Zeitraum vor dem Ausführen der Funktion ermöglichen. Beispielsweise wird der folgende Code, der nach 1 Sekunde auf der Webseite geladen wurde, nach dem Seitendokument hinzugefügt:
Die Codekopie lautet wie folgt:
var onesecond = 1000 * 1; // eine Sekunde = 1000 x 1 ms
setTimeout (function () {
document.write ('<p> Hallo dort. </p>');
}, Onesecond);
und setInterval ermöglicht eine wiederholte Ausführung von Funktionen in bestimmten Zeitintervallen. Wenn der folgende Code in die Webseite eingeleitet wird, wird der folgende Satz "Hello there" jede Sekunde zum Seitendokument hinzugefügt:
Die Codekopie lautet wie folgt:
var onesecond = 1000 * 1; // eine Sekunde = 1000 x 1 ms
setInterval (function () {
document.write ('<p> Hallo dort. </p>');
}, Onesecond);
Da das Web seit langem zu einer Plattform für den Aufbau von Anwendungen und nicht zu einer einfachen statischen Seite geworden ist, entsteht diese Art von ähnlicher Nachfrage zunehmend. Diese Aufgabenplanungsfunktionen helfen Entwicklern dabei, eine regelmäßige Überprüfung von Formularen, die Verzögerung der Ferndatensynchronisation oder die UI -Wechselwirkungen zu implementieren, die verzögerte Antworten erfordern. Der Knoten implementiert diese Methoden auch vollständig. Auf der Serverseite können Sie sie verwenden, um die Ausführung vieler Aufgaben zu wiederholen oder zu verzögern, wie z. B. Cache -Ablauf, Verbindungspoolreinigung, Ablauf der Sitzung, Ablauf und mehr.
Führen Sie mithilfe der SetTimeout -Verzögerungsfunktion aus
SetTimeOut kann einen Ausführungsplan erstellen, der die angegebene Funktion einmal zu einem bestimmten Zeitpunkt in der Zukunft ausführt, z. B.:
Die Codekopie lautet wie folgt:
var timeout_ms = 2000; // 2 Sekunden
var timeout = setTimeout (function () {
console.log ("Timed Out!");
}, timeout_ms);
Wie Client JavaScript akzeptiert SetTimeOut zwei Parameter. Der erste Parameter ist die Funktion, die verzögert werden muss, und der zweite Parameter ist die Verzögerungszeit (in Millisekunden).
SetTimeOut gibt einen Zeitüberschreitungsgriff zurück, bei dem es sich um ein internes Objekt handelt. Sie können es als Parameter verwenden, um ClearTimeout aufzurufen, um den Timer abzubrechen. Abgesehen davon hat dieser Griff keinen Einfluss.
Verwenden Sie Clearimeout, um den Ausführungsplan zu stornieren
Sobald das Timeout -Handle erhalten wurde, können Sie Clearimeout verwenden, um den Funktionsausführungsplan wie folgt zu stornieren:
Die Codekopie lautet wie folgt:
var timeouttime = 1000; // eine Sekunde
var timeout = setTimeout (function () {
console.log ("Timed Out!");
}, TimeoutTime);
Clearimeout (Zeitüberschreitung);
In diesem Beispiel wird der Timer niemals ausgelöst und geben die Wörter "Time Out!" NICHT aus. Sie können den Ausführungsplan auch jederzeit in der Zukunft stornieren, z. B. das folgende Beispiel:
Die Codekopie lautet wie folgt:
var timeout = setTimeout (Funktion a () {
console.log ("Timed Out!");
}, 2000);
setTimeout (Funktion b () {
Clearimeout (Zeitüberschreitung);
}, 1000);
Der Code gibt zwei Funktionen A und B an, die verzögert ausgeführt werden. Die Funktion A ist geplant, nach 2 Sekunden ausgeführt zu werden, und B soll nach 1 Sekunde ausgeführt werden, da die Funktion B zuerst ausgeführt wird und den Ausführungsplan von A abbricht, sodass A niemals ausgeführt werden wird.
Entwickeln und stornieren Sie den sich wiederholenden Ausführungsplan der Funktion
setInterval ähnelt SetTimeOut, wird jedoch wiederholt eine Funktion in einem bestimmten Zeitintervall ausführen. Sie können es verwenden, um ein Programm regelmäßig auszulösen, um einige andere Aufgaben zu erledigen, die wiederholt werden müssen, z. B. Reinigen, Sammeln, Protokollieren, Daten, Umfragen usw.
Der folgende Code gibt jede Sekunde eine "Hähne" an die Konsole aus:
Die Codekopie lautet wie folgt:
var period = 1000; // 1 Sekunde
setInterval (function () {
console.log ("tick");
}, Zeitraum);
Wenn Sie nicht möchten, dass es für immer läuft, können Sie ClearInterval () verwenden, um den Timer abzubrechen.
setInterval gibt einen Ausführungsplan -Handle zurück, der als Parameter für ClearInterval verwendet werden kann, um den Ausführungsplan zu stornieren:
Die Codekopie lautet wie folgt:
var inval = setInterval (function () {
console.log ("tick");
}, 1000);
//…
ClearInterval (Intervall);
Verwenden Sie Process.NextTick, um die Funktionsausführung in die nächste Runde der Ereignisschleife zu verzögern
Manchmal verwendet der Client JavaScript -Programmierer SetTimeOut (Callback, 0), um die Aufgabe für einen kurzen Zeitraum zu verzögern. Der zweite Parameter beträgt 0 Millisekunden. Es teilt JavaScript mit, dass er diese Rückruffunktion unmittelbar nach allen ausstehenden Ereignissen ausführen soll. Manchmal wird diese Technik verwendet, um die Ausführung von Operationen zu verzögern, die nicht sofort durchgeführt werden müssen. Beispielsweise müssen Sie beispielsweise mit dem Abspielen von Animationen beginnen oder andere Berechnungen durchführen, nachdem das Benutzerereignis verarbeitet wurde.
Im Knoten läuft die Ereignisschleife genau wie die wörtliche Bedeutung von "Ereignisschleife" in einer Schleife, die Ereigniswarteschlangen übernimmt, und jede Runde in der Event -Loop -Arbeit wird als Zecke bezeichnet.
Sie können die Rückruffunktion jedes Mal aufrufen, wenn die Ereignisschleife die nächste Runde (nächste Tick) ausführt, die genau das Prinzip des Prozesses ist.
Durch die Verwendung von Process.NextTick (Callback) anstelle von SetTimeout (Callback, 0) wird Ihre Rückruffunktion unmittelbar nach dem Ereignis in der Warteschlange ausgeführt. Es ist viel schneller als die JavaScript -Timeout -Warteschlange (gemessen mit der CPU -Zeit).
Sie können die Funktion bis zur nächsten Ereignisschleife verzögern und sie so ausführen:
Die Codekopie lautet wie folgt:
process.nextTick (function () {
my_exPensive_computation_function ();
});
Hinweis: Das Prozessobjekt ist eines der wenigen globalen Objekte im Knoten.
Blockierungsereignisschleife
Die Laufzeit von Node und JavaScript verwendet eine Ereignisschleife mit einem Thread. In jeder Schleife verwendet die Laufzeit die Rückruffunktion, um das nächste Ereignis in der Warteschlange zu verarbeiten. Wenn das Ereignis ausgeführt wird, erhält die Ereignisschleife das Ausführungsergebnis und verarbeitet das nächste Ereignis, um dies zu wiederholen, bis die Ereigniswarteschlange leer ist. Wenn einer der Rückrufe lange dauert, kann die Ereignisschleife in dieser Zeit keine anderen anstehenden Ereignisse erledigen, wodurch die Anwendung oder den Dienst sehr langsam gestaltet werden kann.
Bei der Verarbeitung von Ereignissen, wenn speicherempfindliche oder prozessorsensitive Funktionen verwendet werden, wird die Ereignisschleife langsam und eine große Anzahl von Ereignissen sammelt sich an, die nicht rechtzeitig verarbeitet werden können oder die Warteschlange sogar blockiert.
Siehe das folgende Beispiel für die Blockierung der Ereignisschleife:
Die Codekopie lautet wie folgt:
process.nextTick (Funktion NextTick1 () {
var a = 0;
while (wahr) {
a ++;
}
});
process.nextTick (Funktion NextTick2 () {
console.log ("Next Tick");
});
setTimeout (Funktion Timeout () {
console.log ("timeout");
}, 1000);
In diesem Beispiel haben NextTick2- und Timeout -Funktionen keine Chance, zu laufen, egal wie lange sie warten, da die Ereignisschleife in der NextTick -Funktion durch die Infinite -Schleife blockiert wird und nicht ausgeführt wird, auch wenn die Timeout -Funktion nach 1 Sekunde ausgeführt werden soll.
Wenn SetTimeout verwendet wird, werden die Rückruffunktionen zur Warteschlange zur Ausführungsplan hinzugefügt und in diesem Fall nicht einmal der Warteschlange hinzugefügt. Obwohl dies ein extremes Beispiel ist, können Sie sehen, dass das Ausführen einer prozessorempfindlichen Aufgabe die Ereignisschleife blockieren oder verlangsamen kann.
Beenden Sie die Ereignisschleife
Mit Process.NextTick kann eine nicht kritische Aufgabe vor der Ausführung in die nächste Runde der Ereignisschleife (Tick) verschoben werden, die die Ereignisschleife freigeben kann, damit sie weiterhin andere anstehende Ereignisse ausführen kann.
Siehe das folgende Beispiel. Wenn Sie vorhaben, eine temporäre Datei zu löschen, aber nicht möchten, dass die Rückruffunktion des Datenereignisses auf diesen IO -Vorgang wartet, können Sie sie so verzögern:
Die Codekopie lautet wie folgt:
Stream.on ("Daten", Funktion (Daten) {
Stream.end ("meine Antwort");
process.nextTick (function () {
fs.unlink ("/path/to/file");
});
});
Verwenden Sie SetTimeout anstelle von setInterval, um die Serialität der Funktionsausführung sicherzustellen
Angenommen, Sie planen, eine Funktion namens My_async_function zu entwerfen, die einige E/A -Operationen (z. B. Analyseprotokolldateien) ausführen kann und beabsichtigt, sie regelmäßig auszuführen. Sie können es mit SetInterval wie folgt implementieren:
Die Codekopie lautet wie folgt:
var intervall = 1000;
setInterval (function () {
my_async_function (function () {
console.log ('my_async_function fertig!');
});
}, Intervall); // Übersetzer Anmerkung: Ich habe das vorherige ", Intervall" hinzugefügt und der Autor hätte es aufgrund eines Tippfehlers übersehen müssen
Sie müssen in der Lage sein, sicherzustellen, dass diese Funktionen nicht gleichzeitig ausgeführt werden. Wenn Sie SetInterval verwenden, können Sie dies jedoch nicht garantieren. Wenn die Funktion my_async_function eine Millisekunde länger als die Intervallvariablen ausführt, werden sie gleichzeitig ausgeführt und nicht seriell in der Sequenz.
Anmerkung des Übersetzers: (Der mutige Teil unten wird vom Übersetzer hinzugefügt, nicht der Inhalt des Originalbuchs)
Um das Verständnis dieses Teils des Inhalts zu erleichtern, können Sie den Code des Autors so ändern, dass er tatsächlich ausgeführt wird:
Die Codekopie lautet wie folgt:
var intervall = 1000;
setInterval (function () {
(Funktion my_async_function () {
setTimeout (function () {
console.log ("1");
}, 5000);
}) ();
},Intervall);
Führen Sie diesen Code aus und Sie werden feststellen, dass "Hallo" nach 5 Sekunden lang alle 1 Sekunde ausgegeben wird. Wir gehen davon aus, dass nach der Ausführung des aktuellen my_async_function (5 Sekunden) 1 Sekunde vor dem Ausführen des nächsten my_async_function ausgesetzt wurde und das Intervall zwischen den einzelnen Ausgaben 6 Sekunden betragen sollte. Dieses Ergebnis liegt daran, dass my_async_function nicht seriell ausgeführt wird, sondern gleichzeitig ausgeführt wird.
Daher benötigen Sie eine Möglichkeit, das Intervall zwischen dem Ende einer Ausführung einer my_async_function und dem Beginn der Ausführung der nächsten my_async_function zu erzwingen, genau die Zeit, die durch die Intervallvariable angegeben ist. Sie können das tun:
Die Codekopie lautet wie folgt:
var intervall = 1000; // 1 Sekunde
(Funktionsplan () {// Zeile 3
setTimeout (Funktion do_it () {
my_async_function (function () {// Zeile 5
console.log ('async ist fertig!');
Zeitplan();
});
}, Intervall);
} ()); // Zeile 10
Im vorherigen Code wird eine Funktion namens Schedule (Zeile 3) deklariert und unmittelbar nach der Deklaration (Zeile 10) aufgerufen. In der Zeitplanfunktion wird die Funktion do_it nach 1 Sekunde ausgeführt (angegeben mit Intervall). Nach 1 Sekunde wird die Funktion my_async_function in Zeile 5 aufgerufen. Wenn es ausgeführt wird, ruft es eine eigene anonyme Rückruffunktion (Zeile 6) an. Diese anonyme Rückruffunktion setzt den Ausführungsplan von do_it erneut zurück und lässt ihn nach 1 Sekunde erneut ausgeführt werden, damit der Code seriell und kontinuierlich ausgeführt wird.
Zusammenfassung
Sie können die Funktion setTimeout () verwenden, um den Ausführungsplan der Funktion vorzustellen und sie mit der Funktion clearimeout () abzusagen. Sie können auch setInterval () verwenden, um eine bestimmte Funktion regelmäßig wiederholt auszuführen. Dementsprechend können Sie ClearInterval () verwenden, um diesen wiederholten Ausführungsplan zu stornieren.
Wenn die Ereignisschleife unter Verwendung eines prozessorempfindlichen Betriebs blockiert wird, werden die ursprünglich geplanten Funktionen verzögert und niemals ausgeführt. Verwenden Sie also keine CPU-sensitiven Operationen innerhalb der Ereignisschleife. Außerdem können Sie Process.NextTick () verwenden, um die Ausführung der Funktion bis zur nächsten Runde der Ereignisschleife zu verzögern.
Wenn Sie mit E/A und setInterval () zusammen verwenden, können Sie zu keinem Zeitpunkt garantieren, dass es nur einen anhängigen Anruf gibt. Sie können jedoch rekursive Funktionen und SetTimeOut () -Funktionen verwenden, um dieses knifflige Problem zu vermeiden.