Wenn Sie mit der clientseitigen JavaScript-Programmierung vertraut sind, haben Sie möglicherweise die Funktionen setTimeout und setInterval verwendet, die eine Verzögerung bei der Ausführung einer Funktion für einen bestimmten Zeitraum ermöglichen. Beispielsweise hängt der folgende Code nach dem Laden in die Webseite nach 1 Sekunde „Hallo“ an das Seitendokument an:
setTimeout(function() {
document.write('
Hallo.
');}, oneSecond);
Und setInterval ermöglicht die wiederholte Ausführung der Funktion in bestimmten Intervallen. Wenn der folgende Code in eine Webseite eingefügt wird, wird jede Sekunde „Hallo“ an das Seitendokument angehängt:
setInterval(function() {
document.write('
Hallo.
'); }, oneSecond);
Da das Web längst zu einer Plattform zum Erstellen von Anwendungen und nicht mehr zu einfachen statischen Seiten geworden ist, entstehen solche Anforderungen zunehmend. Diese Aufgabenplanungsfunktionen helfen Entwicklern bei der Implementierung regelmäßiger Formularvalidierungen, verzögerter Remote-Datensynchronisierung oder UI-Interaktionen, die verzögerte Antworten erfordern. Node implementiert diese Methoden auch vollständig. Auf der Serverseite können Sie damit viele Aufgaben wiederholen oder verzögern, z. B. Cache-Ablauf, Bereinigung des Verbindungspools, Sitzungsablauf, Abfragen usw.
Verwenden Sie die Verzögerungsfunktion setTimeout, um
auszuführensetTimeout kann einen Ausführungsplan formulieren, um die angegebene Funktion einmal in der Zukunft auszuführen, wie zum Beispiel:
var timeout = setTimeout(function() {
console.log("Zeitüberschreitung!");
}, timeout_ms);
Genau wie clientseitiges 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 ein Timeout-Handle 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.
Verwenden Sie „clearTimeout“, um den Ausführungsplan abzubrechen
Sobald Sie das Timeout-Handle erhalten haben, können Sie „clearTimeout“ verwenden, um den Funktionsausführungsplan wie folgt abzubrechen:
var timeout = setTimeout(function() {
console.log("Zeitüberschreitung!");
}, timeoutTime);
clearTimeout(timeout);
In diesem Beispiel wird weder der Timer ausgelöst, noch werden die Worte „Timeout!“ ausgegeben. Sie können den Ausführungsplan auch jederzeit für die Zukunft stornieren, wie im folgenden Beispiel:
Erstellen und stornieren Sie wiederholte Ausführungspläne für Funktionen
setInterval ähnelt setTimeout, führt jedoch eine Funktion wiederholt in bestimmten Intervallen aus. Sie können es verwenden, um ein Programm regelmäßig auszulösen, um Aufgaben wie Bereinigung, Erfassung, Protokollierung, Datenerfassung, Abfrage usw. abzuschließen, die wiederholt ausgeführt werden müssen.Der folgende Code gibt jede Sekunde ein „Tick“ an die Konsole aus:
console.log("tick");
}, Punkt);
setInterval gibt ein Ausführungsplan-Handle zurück, das als Parameter von clearInterval verwendet werden kann, um den Ausführungsplan abzubrechen:
}, 1000);
// …
clearInterval(interval);
Verwenden Sie process.nextTick, um die Funktionsausführung bis zur nächsten Runde der Ereignisschleife zu verzögern
Manchmal verwenden clientseitige JavaScript-Programmierer setTimeout(callback,0), um die Aufgabe um einen kurzen Zeitraum zu verzögern. Der zweite Parameter ist 0 Millisekunden, was der JavaScript-Laufzeitumgebung mitteilt, sofort zu warten, nachdem alle ausstehenden Ereignisse verarbeitet wurden. Führen Sie diese Rückruffunktion aus. Manchmal wird diese Technik verwendet, um die Ausführung von Vorgängen zu verzögern, die nicht sofort ausgeführt werden müssen. Beispielsweise müssen Sie manchmal mit der Wiedergabe einer Animation beginnen oder andere Berechnungen durchführen, nachdem das Benutzerereignis verarbeitet wurde.
In Node wird die Ereignisschleife genau wie die wörtliche Bedeutung von „Ereignisschleife“ in einer Schleife ausgeführt, die die Ereigniswarteschlange verarbeitet. Jede Runde des Arbeitsprozesses der Ereignisschleife wird als Tick bezeichnet.
Sie können die Rückruffunktion jedes Mal aufrufen, wenn die Ereignisschleife die nächste Ausführungsrunde (nächsten Tick) startet. Dies ist genau das Prinzip von process.nextTick, und setTimeout und setTimeout verwenden die Ausführungswarteschlange innerhalb der JavaScript-Laufzeit Ereignisschleife wird nicht verwendet.
Durch die Verwendung von process.nextTick(callback) anstelle von setTimeout(callback, 0) wird Ihre Callback-Funktion unmittelbar nach der Verarbeitung des Ereignisses in der Warteschlange ausgeführt, was viel schneller ist als die Timeout-Warteschlange von JavaScript (in gemessener CPU-Zeit). ).
Sie können die Funktion wie folgt bis zur nächsten Runde der Ereignisschleife verzögern:
my_expensive_computation_function();
});
Hinweis: Das Prozessobjekt ist eines der wenigen globalen Objekte in Node.
Blockieren der Ereignisschleife
Die Laufzeit von Node und JavaScript verwendet eine Single-Threaded-Ereignisschleife. Bei jeder Schleife verarbeitet die Laufzeit das nächste Ereignis in der Warteschlange, indem sie die entsprechende Rückruffunktion aufruft. Wenn das Ereignis ausgeführt wird, ruft die Ereignisschleife das Ausführungsergebnis ab und verarbeitet das nächste Ereignis usw., bis die Ereigniswarteschlange leer ist. Wenn die Ausführung einer der Rückruffunktionen lange dauert, kann die Ereignisschleife während dieser Zeit keine anderen ausstehenden Ereignisse verarbeiten, was die Anwendung oder den Dienst sehr langsam machen kann.
Wenn bei der Verarbeitung von Ereignissen speicherempfindliche oder prozessorempfindliche Funktionen verwendet werden, wird die Ereignisschleife langsam und es sammelt sich eine große Anzahl von Ereignissen an, die nicht rechtzeitig verarbeitet werden können oder sogar die Warteschlange blockieren.
Sehen Sie sich das folgende Beispiel für das Blockieren der Ereignisschleife an:
var a = 0;
while(true) {
ein ;
}
});process.nextTick(function nextTick2() {
console.log("nächster Tick");
});
setTimeout(function timeout() {
console.log("timeout");
}, 1000);
Bei Verwendung von setTimeout werden die Rückruffunktionen zur Ausführungsplanwarteschlange hinzugefügt, und in diesem Beispiel werden sie nicht einmal zur Warteschlange hinzugefügt. Dies ist ein extremes Beispiel, aber Sie sehen, dass die Ausführung einer prozessorintensiven Aufgabe die Ereignisschleife blockieren oder verlangsamen kann.
Verlassen Sie die Ereignisschleife
Mit Process.nextTick können Sie die Ausführung einer nicht kritischen Aufgabe auf den nächsten Tick der Ereignisschleife verschieben, wodurch die Ereignisschleife freigegeben wird, sodass sie weiterhin andere ausstehende Ereignisse ausführen kann.Sehen Sie sich das folgende Beispiel an. Wenn Sie planen, eine temporäre Datei zu löschen, aber nicht möchten, dass die Rückruffunktion des Datenereignisses auf diesen E/A-Vorgang wartet, können Sie ihn wie folgt verzögern:
process.nextTick(function() {
fs.unlink("/path/to/file");
});
});
Angenommen, Sie planen, eine Funktion namens my_async_function zu entwerfen, die bestimmte E/A-Vorgänge ausführen kann (z. B. das Parsen von Protokolldateien), und beabsichtigen, sie regelmäßig ausführen zu lassen. Sie können setInterval verwenden, um sie wie folgt zu implementieren:
setInterval(function() {
my_async_function(function() {
console.log('my_async_function done!');
});
},interval);//Anmerkung des Übersetzers: Das vorherige „,interval“ wurde von mir hinzugefügt, der Autor hat es möglicherweise aufgrund eines Tippfehlers weggelassen
Anmerkung des Übersetzers: (Die fett gedruckten Teile unten wurden vom Übersetzer hinzugefügt und sind 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 werden kann:
(function my_async_function(){
setTimeout(function(){
console.log("1");
},5000);
},Intervall);
Führen Sie diesen Code aus und schauen Sie nach. Sie werden feststellen, dass nach 5 Sekunden Wartezeit alle 1 Sekunde „Hallo“ ausgegeben wird. Wir erwarten, dass nach der Ausführung der aktuellen my_async_function (es dauert 5 Sekunden) 1 Sekunde gewartet wird, bevor die nächste my_async_function ausgeführt wird. Zwischen den einzelnen Ausgaben sollte ein Intervall von 6 Sekunden liegen. Dieses Ergebnis wird durch die Tatsache verursacht, dass my_async_function nicht seriell ausgeführt wird, sondern mehrere gleichzeitig ausgeführt werden.