Heim >Web-Frontend >js-Tutorial >Vertiefendes Verständnis der Ereignisschleife und Rückruffunktionen von Node.j

Vertiefendes Verständnis der Ereignisschleife und Rückruffunktionen von Node.j

高洛峰
高洛峰Original
2016-12-08 10:26:531564Durchsuche

In diesem Artikel werden die Node.js-Ereignisschleife und die Node.js-Rückruffunktion im Detail vorgestellt. Ich werde nicht auf allzu viel Unsinn eingehen.

1. Node.js-Ereignisschleife

Node.js ist eine Einzelprozess- und Einzelthread-Anwendung, unterstützt jedoch Parallelität durch Ereignisse und Rückrufe, sodass die Leistung sehr hoch ist hoch. Jede API in Node.js ist asynchron und wird als separater Thread ausgeführt, verwendet asynchrone Funktionsaufrufe und verarbeitet Parallelität. Grundsätzlich werden alle Ereignismechanismen in Node.js mithilfe des Beobachtermusters im Entwurfsmuster implementiert. Der einzelne Thread von Node.j ähnelt dem Eintritt in eine while(true)-Ereignisschleife, bis kein Ereignisbeobachter mehr auftritt. Wenn ein Ereignis auftritt, wird die Callback-Funktion aufgerufen -gesteuertes Programm


Node.js verwendet das ereignisgesteuerte Modell. Wenn der Webserver eine Anfrage empfängt, schließt er diese, verarbeitet sie und bedient dann die nächste Webanfrage. Wenn die Anfrage abgeschlossen ist, wird sie wieder in die Verarbeitungswarteschlange gestellt, und wenn der Kopf der Warteschlange erreicht ist, wird das Ergebnis an den Benutzer zurückgegeben. Dieses Modell ist sehr effizient und skalierbar, da der Webserver immer Anfragen entgegennimmt, ohne auf Lese- oder Schreibvorgänge warten zu müssen. (Dies wird auch als nicht blockierendes IO oder ereignisgesteuertes IO bezeichnet). Im ereignisgesteuerten Modell wird eine Hauptschleife generiert, um auf Ereignisse zu warten und eine Rückruffunktion auszulösen, wenn ein Ereignis erkannt wird.


So wird der gesamte ereignisgesteuerte Prozess umgesetzt, was sehr einfach ist. Ähnlich wie beim Beobachtermuster entspricht das Ereignis einem Subjekt (Subject) und alle für dieses Ereignis registrierten Handlerfunktionen entsprechen Beobachtern (Observer). Node.js verfügt über mehrere integrierte Ereignisse. Wir können Ereignisse binden und abhören, indem wir das Ereignismodul einführen und die EventEmitter-Klasse instanziieren, wie im folgenden Beispiel gezeigt:


// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();
以下程序绑定事件处理程序:
// 绑定事件及事件的处理程序
eventEmitter.on('eventName', eventHandler);
我们可以通过程序触发事件:
// 触发事件
eventEmitter.emit('eventName');

2. Beispiel


Erstellen Sie die Datei main.js, der Code lautet wie folgt:

// 引入 events 模块
var events = require('events');
// 创建 eventEmitter 对象
var eventEmitter = new events.EventEmitter();
// 创建事件处理程序
var connectHandler = function connected() {
  console.log('连接成功。');
  // 触发 data_received 事件
  eventEmitter.emit('data_received');
}
// 绑定 connection 事件处理程序
eventEmitter.on('connection', connectHandler);
// 使用匿名函数绑定 data_received 事件
eventEmitter.on('data_received', function(){
  console.log('数据接收成功。');
});
// 触发 connection 事件
eventEmitter.emit('connection');
console.log("程序执行完毕。");

2. Node.js Rückruffunktion


Die direkte Manifestation der asynchronen Programmierung von Node.j ist der Rückruf. Die asynchrone Programmierung basiert auf Rückrufen, es kann jedoch nicht gesagt werden, dass das Programm nach der Verwendung von Rückrufen asynchron wird. Die Rückruffunktion wird nach Abschluss der Aufgabe aufgerufen. Node verwendet eine große Anzahl von Rückruffunktionen. Beispielsweise können wir eine Datei lesen, während wir andere Befehle ausführen. Nachdem das Lesen der Datei abgeschlossen ist, geben wir den Dateiinhalt als Parameter der Callback-Funktion zurück. Auf diese Weise gibt es beim Ausführen von Code keine Blockierungen oder Wartezeiten für Datei-E/A-Vorgänge. Dies verbessert die Leistung von Node.js erheblich und kann eine große Anzahl gleichzeitiger Anforderungen verarbeiten.

1. Blockierungscode-Beispiel


Erstellen Sie eine Datei test.txt mit folgendem Inhalt:

Hello World!
fs.readFileSync()
fs.readFile()

Test.js-Datei erstellen, der Code lautet wie folgt:

console.log('-------程序开始执行--------'); 
// 引入fs模块
var fs = require("fs");
//同步读取文件
var data = fs.readFileSync('test.txt','utf-8');
console.log(data.toString());
console.log('-------程序执行结束--------');

Das Ausführungsergebnis des obigen Codes lautet wie folgt:


2. Nicht blockierendes Codebeispiel


Erstellen Sie die Datei test.js. Der Code lautet wie folgt:

console.log('-------程序开始执行--------'); 
// 引入fs模块
var fs = require("fs");
//异步读取文件
fs.readFile('test.txt','utf-8',function (err, data) {
  if (err) return console.error(err);
  console.log(data.toString());
});
console.log('-------程序执行结束--------');

Im obigen Programm ist fs.readFile() eine asynchrone Funktion, die zum Lesen von Dateien verwendet wird. Wenn beim Lesen der Datei ein Fehler auftritt, gibt das Fehler-Err-Objekt Fehlerinformationen aus. Wenn kein Fehler auftritt, überspringt readFile die Ausgabe des err-Objekts und der Dateiinhalt wird über die Callback-Funktion ausgegeben.

Das Ausführungsergebnis des obigen Codes ist wie folgt:

Als nächstes löschen wir die Datei input.txt und das Ausführungsergebnis ist wie folgt:

In den beiden obigen Beispielen verstehen wir den Unterschied zwischen blockierenden und nicht blockierenden Anrufen. Die erste Instanz führt das Programm erst aus, nachdem die Datei gelesen wurde. Im zweiten Beispiel müssen wir nicht auf das Lesen der Datei warten, sodass der nächste Code gleichzeitig mit dem Lesen der Datei ausgeführt werden kann, was die Leistung des Programms erheblich verbessert. Daher wird die Blockierung der Reihe nach ausgeführt, die Nichtblockierung muss jedoch nicht der Reihe nach erfolgen. Wenn wir also die Parameter der Rückruffunktion verarbeiten müssen, müssen wir sie in die Rückruffunktion schreiben.

3. fs.readFileSync und fs.readFile


1. s.readFileSync

Syntax: fs.readFileSync(filename, [encoding])

Empfangsparameter:

Dateiname: Dateipfad

Optionen: Optionsobjekt, einschließlich Kodierung, Kodierungsformat, dieses Element ist optional.

Da Node.js nur die folgenden Kodierungen unterstützt: utf8, ucs2, ASCII, Binär, Base64, Hex, unterstützt es keine Kodierungen wie Chinesisch GBK oder GB2312, wenn Sie also Dateien lesen und schreiben möchten GBK- oder GB2312-Format Für chinesische Inhalte muss ein zusätzliches Modul verwendet werden: iconv-lite.

2. fs.readFile

Syntax: fs.readFile(filename, [encoding], [callback(err,data)])

Empfangsparameter:

Dateiname: Dateipfad

Optionen: Optionsobjekt, einschließlich Kodierung, Kodierungsformat, dieses Element ist optional.

Rückruf: Rückruf, Übergabe von 2 Parametern: Ausnahmefehler und Dateiinhaltsdaten

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