Heim >Web-Frontend >js-Tutorial >Zusammenfassung der nicht blockierenden E/A- und Ereignisschleife in Node.js_node.js
Es ist zwei Monate her, seit ich Node.js gelernt und verwendet habe. Ich habe Express in Kombination mit Mongoose verwendet, um eine Webanwendung und eine Reihe von RESTful-Web-APIs zu schreiben Offizielle Website von Node.js: Node.js verwendet ein ereignisgesteuertes, nicht blockierendes I/O-Modell, das es leichtgewichtig und effizient macht. Was bedeutet also das nicht blockierende I/O-Modell?
Nicht blockierendes IO-Modell
Erstens sind E/A-Vorgänge zweifellos zeitaufwändig. Wenn der Server eine große Anzahl von Anforderungen erhält, verursacht das Erstellen eines Prozesses oder Threads für jede Anforderung auch zusätzlichen Speicheraufwand und kann mehr Zeitressourcen verschwenden.
Da Node.js ereignisgesteuert ist, verwendet es eine Ereignisschleife, um das durch E/A-Vorgänge verursachte Engpassproblem zu lösen. In Node.js verfügt eine E/A-Operation normalerweise über eine Rückruffunktion. Wenn die E/A-Operation abgeschlossen ist und zurückkehrt, wird die Rückruffunktion aufgerufen und der Hauptthread führt weiterhin den nächsten Code aus. Lassen Sie uns dieses Problem einfach anhand eines Beispiels veranschaulichen:
request('http://www.google.com', function(error, response, body) { console.log(body); }); console.log('Done!');
Die Bedeutung dieses Codes besteht darin, eine Anfrage an „http://www.google.com“ zu stellen. Wenn die Anfrage zurückkommt, wird die Rückruffunktion aufgerufen, um die Antwortinformationen auszugeben. Aufgrund des Betriebsmechanismus von Node.js wird nach der Ausführung dieses Codes sofort „Fertig!“ an die Konsole ausgegeben und nach einiger Zeit werden die Antwortinformationen ausgegeben.
Ereignisschleife Ereignisschleife
Als nächstes besprechen wir den Mechanismus der Ereignisschleife. Lassen Sie uns zunächst über den Aufruf von 桟 sprechen. Es gibt beispielsweise den folgenden Code:
function A(arg, func){ var a = arg; func(); console.log('A'); } function B(){ console.log('B'); } A(0, B);
Wenn der Code ausgeführt wird, wird Funktion A zunächst in den aufrufenden Bucket geschoben, um das oberste Element des Stapels zu werden, und beginnt mit der Ausführung von A. Während des Ausführungsprozesses wird Funktion B in den aufrufenden Bucket geschoben, um das oberste Element von zu werden Nachdem die Ausführung von B abgeschlossen ist, wird A wieder zum obersten Element des Stapels. Nachdem die Ausführung von A abgeschlossen ist, wird A aus dem aufrufenden Stapel entfernt Der aufrufende Stapel wird inaktiv.
In der Javascript-Laufzeit gibt es eine Nachrichtenwarteschlange, und die Nachricht ist einer Rückruffunktion zugeordnet. Wenn ein Ereignis ausgelöst wird und das Ereignis über eine entsprechende Rückruffunktion verfügt, wird die Nachricht der Nachrichtenwarteschlange hinzugefügt.
Wenn man sich anschaut, worum es in der Ereignisschleife genau geht, werden Funktionen kontinuierlich in den aufrufenden Bucket verschoben, nachdem der Code ausgeführt wurde. Nehmen wir das obige Beispiel: Die Anforderung wird in den aufrufenden Bucket verschoben und diese Funktion wird als http ausgeführt Anfrage (Diese HTTP-Anfrage wird vom zugrunde liegenden Modul von Node.js implementiert. Gleichzeitig wird das Ereignis der Anforderungsvervollständigung mit einer Rückruffunktion verknüpft. Die Anforderung wird aus dem aufrufenden Stapel entfernt, und console.log wird ausgeführt in den aufrufenden Stapel geschoben, um die Ausführung zu starten. Wenn die Anforderung abgeschlossen ist, wird das Abschlussereignis ausgelöst und eine Nachricht zur Nachrichtenwarteschlange hinzugefügt. Die Nachrichtenwarteschlange prüft zunächst, ob der aufrufende Stacker inaktiv ist Leerlauf und dann Der Kopf der Nachrichtenwarteschlange wird angezeigt und die mit der Nachricht verknüpfte Rückruffunktion wird ausgeführt.
Zusammenfassung
Das Obige ist eine konzeptionelle Zusammenfassung des nicht blockierenden Modells und der Ereignisschleife. Dieser Ereignisschleifenmechanismus gibt es nicht nur bei Node.js, und der Code von Node.js wird in einem einzelnen Thread ausgeführt. Welche Vorteile hat er, wenn eine große Anzahl gleichzeitiger Anforderungen auftritt?
Das obige Bild zeigt das Architekturdiagramm von Node.js. Am unteren Ende von Node.js befindet sich ein Modul, das für die Verwaltung des Thread-Pools verantwortlich ist Erstellen Sie einen neuen Thread, um die Anforderung zu verarbeiten, und geben Sie die Ergebnisse nach Abschluss an die obere Ebene zurück. Wenn dann mehrere Anforderungen vorliegen, verwendet das zugrunde liegende Modul von Node.js so wenige Threads wie möglich, um die meisten Aufgaben zu erledigen. Wenn es inaktive Threads gibt, wird es weiterhin für andere Aufgaben verwendet, was ich gesagt habe Im Hinblick auf das Öffnen eines neuen Prozesses oder Threads für jede Anfrage ist es zweifellos viel „intelligenter“ und effizienter.
Dieser Artikel ist eine Zusammenfassung des Lernens von Node.js. Wenn es Probleme oder Mängel gibt, können Sie mich gerne kritisieren und korrigieren.