Heim  >  Artikel  >  Web-Frontend  >  Ausführliche Erläuterung der Verwendung von Timern zur regelmäßigen Ausführung von Funktionen in Node.js_node.js

Ausführliche Erläuterung der Verwendung von Timern zur regelmäßigen Ausführung von Funktionen in Node.js_node.js

WBOY
WBOYOriginal
2016-05-16 16:39:341357Durchsuche

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:

Code kopieren Der Code lautet wie folgt:

var oneSecond = 1000 * 1; // eine Sekunde = 1000 x 1 ms

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:

Code kopieren Der Code lautet wie folgt:

                var oneSecond = 1000 * 1; // eine Sekunde = 1000 x 1 ms

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ühren

setTimeout kann einen Ausführungsplan formulieren, um die angegebene Funktion einmal in der Zukunft auszuführen, wie zum Beispiel:

Code kopieren Der Code lautet wie folgt:

                      var timeout_ms = 2000; // 2 Sekunden

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:

Code kopieren Der Code lautet wie folgt:

                    var timeoutTime = 1000 // eine Sekunde

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:

Code kopieren Der Code lautet wie folgt:

var timeout = setTimeout(function A() {

console.log("Zeitüberschreitung!");

                      }, 2000);

                                      setTimeout(function B() {

                                                                                                                                                                                                                                            
                     }, 1000);

Der Code gibt zwei verzögerte Ausführungsfunktionen A und B an. Funktion A soll nach 2 Sekunden ausgeführt werden, und B soll nach 1 Sekunde ausgeführt werden, da Funktion B zuerst ausgeführt wird und den Ausführungsplan von A abbricht. also wird A niemals laufen.

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:


Code kopieren Der Code lautet wie folgt:
                var period = 1000; // 1 Sekunde
setInterval(function() {

console.log("tick");

             }, Punkt);


Wenn Sie nicht möchten, dass es ewig läuft, können Sie den Timer mit „clearInterval()“ abbrechen.

setInterval gibt ein Ausführungsplan-Handle zurück, das als Parameter von clearInterval verwendet werden kann, um den Ausführungsplan abzubrechen:

Code kopieren Der Code lautet wie folgt:
                var Interval = setInterval(function() {
console.log("tick");

             }, 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:

Code kopieren Der Code lautet wie folgt:

process.nextTick(function() {

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:

Code kopieren Der Code lautet wie folgt:

process.nextTick(function nextTick1() {

var a = 0;

while(true) {

ein ;

                                                                          }

             });

process.nextTick(function nextTick2() {

console.log("nächster Tick");

             });

setTimeout(function timeout() {

console.log("timeout");

             }, 1000);


In diesem Beispiel haben die Funktionen „nextTick2“ und „timeout“ keine Chance, ausgeführt zu werden, egal wie lange sie warten, da die Ereignisschleife durch die Endlosschleife in der Funktion „nextTick“ blockiert wird, selbst wenn die Ausführung der Funktion „timeout“ danach geplant ist 1 Sekunde läuft es nicht.

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:


Code kopieren Der Code lautet wie folgt:
                   stream.on("data", function(data) {
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 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:

Code kopieren Der Code lautet wie folgt:

              var Interval = 1000;

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


Sie müssen sicherstellen können, dass diese Funktionen nicht gleichzeitig ausgeführt werden. Sie können dies jedoch nicht garantieren, wenn Sie setinterval verwenden. Wenn die Ausführung der Funktion my_async_function eine Millisekunde länger dauert als die Intervallvariable, werden sie ausgeführt gleichzeitig statt in der Reihenfolge.

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:

Code kopieren Der Code lautet wie folgt:
              var Interval = 1000;
setInterval(function(){

(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.

Daher benötigen Sie eine Möglichkeit, das Intervall zwischen dem Ende einer my_async_function-Ausführung und dem Start der nächsten my_async_function so zu erzwingen, dass es genau der durch die Intervallvariable angegebenen Zeit entspricht. Sie können dies tun:


Code kopieren Der Code lautet wie folgt:

                  var Interval = 1000; // 1 Sekunde

(Funktionsplan() { //Zeile 3

setTimeout(function do_it() {

my_async_function(function() { //Zeile 5

console.log('async is done!');

plan();

                                                                                                                                                                     

                            }, Intervall);

                    }());


Im vorherigen Code wird eine Funktion namens „schedule“ deklariert (Zeile 3) und unmittelbar nach der Deklaration aufgerufen (Zeile 10). Die Funktion „schedule“ führt die Funktion „do_it“ nach 1 Sekunde aus (angegeben durch das Intervall). Nach 1 Sekunde wird die Funktion my_async_function in Zeile 5 aufgerufen. Wenn die Ausführung abgeschlossen ist, wird ihre eigene anonyme Rückruffunktion (Zeile 6) aufgerufen, und diese anonyme Rückruffunktion setzt den Ausführungsplan von do_it erneut zurück nach 1 Sekunde, sodass der Code seriell und kontinuierlich in einer Schleife ausgeführt wird.

Zusammenfassung

Sie können die Funktion setTimeout() verwenden, um den Ausführungsplan der Funktion voreinzustellen, und die Funktion clearTimeout() verwenden, um sie abzubrechen. Sie können setInterval() auch verwenden, um eine Funktion regelmäßig wiederholt auszuführen. Dementsprechend können Sie clearInterval() verwenden, um diesen wiederholten Ausführungsplan abzubrechen.

Wenn die Ereignisschleife durch eine prozessorempfindliche Operation blockiert wird, werden Funktionen, deren Ausführung ursprünglich geplant war, verzögert oder sogar nie ausgeführt. Verwenden Sie daher keine CPU-empfindlichen Vorgänge innerhalb der Ereignisschleife. Außerdem können Sie „process.nextTick()“ verwenden, um die Ausführung einer Funktion bis zur nächsten Iteration der Ereignisschleife zu verzögern.

Wenn E/A mit setInterval() verwendet wird, können Sie nicht garantieren, dass zu jedem Zeitpunkt nur ein ausstehender Aufruf vorhanden ist. Sie können jedoch rekursive Funktionen und die Funktion setTimeout() verwenden, um dieses knifflige Problem zu vermeiden.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn