Node.js Callback-Funktionen
Node.js ist eine JavaScript-Laufzeitumgebung, die auf der Chrome V8-Engine basiert. Sie ermöglicht es JavaScript, serverseitig unabhängig vom Browser ausgeführt zu werden.
Eine der Kernfunktionen von Node.js ist sein nicht blockierendes I/O-Modell (Eingabe/Ausgabe), das Node.js sehr geeignet für die Verarbeitung von Netzwerkanwendungen mit hoher Parallelität macht.
Callbacks sind die direkte Verkörperung der asynchronen Programmierung von Node.js.

In Node.js ist eine Callback-Funktion ein asynchrones Programmiermuster, das verwendet wird, um I/O-Operationen wie das Lesen und Schreiben von Dateien, Datenbankinteraktionen und Netzwerkanfragen zu verarbeiten. Diese Operationen dauern normalerweise lange; wenn sie synchron behandelt würden, würden sie die Ausführung des gesamten Programms blockieren, bis die Operation abgeschlossen ist.
Mit Callback-Funktionen kann Node.js anderen Code weiter ausführen, während eine I/O-Operation läuft, und dann den Callback ausführen, sobald die I/O-Operation abgeschlossen ist.
Node.js ist single-threaded, aber es erreicht asynchrone Operationen durch einen ereignisgesteuerten und Callback-Mechanismus.
Anwendungsfälle
- I/O-Operationen wie das Lesen und Schreiben von Dateien.
- Verarbeitung von Netzwerkanfragen.
- Datenbankabfragen.
Zum Beispiel können wir eine Datei lesen und gleichzeitig andere Befehle ausführen. Wenn 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 Blockierung oder Wartezeit für Datei-I/O-Operationen. Dies verbessert die Leistung von Node.js erheblich und ermöglicht die Verarbeitung einer großen Anzahl gleichzeitiger Anfragen.
Callback-Funktionen erscheinen im Allgemeinen als letzter Parameter einer Funktion:
function foo1(name, age, callback) { }
function foo2(value, callback1, callback2) { }
Beispiel
Beispiel für blockierenden Code
Erstellen Sie eine Datei input.txt mit folgendem Inhalt:
Example官网地址:www.example.com
Erstellen Sie eine Datei main.js mit folgendem Code:
Beispiel
var data = fs.readFileSync('input.txt');
console.log(data.toString());
console.log("Programmausführung beendet!");
Das Ausführungsergebnis des obigen Codes ist wie folgt:
$ node main.js Example官网地址:www.example.com 程序执行结束!
Beispiel für nicht blockierenden Code
Erstellen Sie eine Datei input.txt mit folgendem Inhalt:
Example官网地址:www.example.com
Erstellen Sie eine Datei main.js mit folgendem Code:
Beispiel
fs.readFile('input.txt', function (err, data) {
if (err) return console.error(err);
console.log(data.toString());
});
console.log("Programmausführung beendet!");
Parametererklärung:
errEs ist das Fehlerobjekt, und es wird einen Wert haben, wenn das Lesen fehlschlägt.dataEs ist der Dateiinhalt, der gelesen wurde.
Das Ausführungsergebnis des obigen Codes ist wie folgt:
$ node main.js 程序执行结束! Example官网地址:www.example.com
Anhand der beiden obigen Beispiele lässt sich der Unterschied zwischen blockierenden und nicht blockierenden Aufrufen erkennen:
Das erste Beispiel führt das Programm erst aus, nachdem das Lesen der Datei abgeschlossen ist.
Im zweiten Beispiel müssen wir nicht warten, bis das Lesen der Datei abgeschlossen ist, sodass wir während des Lesens der Datei nachfolgenden Code ausführen können, was die Programmleistung erheblich verbessert.
Daher erfolgt die blockierende Ausführung sequenziell, während nicht blockierende Aufrufe keine sequenzielle Reihenfolge erfordern. Wenn Sie also die Parameter der Callback-Funktion verarbeiten müssen, müssen Sie dies innerhalb der Callback-Funktion schreiben.
Callback-Hölle
Wenn mehrere asynchrone Operationen nacheinander ausgeführt werden müssen, führen Callback-Funktionen zu verschachteltem Code, wodurch der Code schwer zu lesen und zu warten ist.
Beispiel
if (err) {
console.error('Fehler beim Lesen von file1:', err);
return;
}
fs.readFile('file2.txt', 'utf8', (err, data2) => {
if (err) {
console.error('Fehler beim Lesen von file2:', err);
return;
}
fs.readFile('file3.txt', 'utf8', (err, data3) => {
if (err) {
console.error('Fehler beim Lesen von file3:', err);
return;
}
console.log('Daten aus allen Dateien:', data1, data2, data3);
});
});
});
Um die Lesbarkeit und Wartbarkeit des Codes zu verbessern, können Sie die folgenden Methoden verwenden:
- Promises: Promises sind ein neues asynchrones Programmiermuster, das es ermöglicht, asynchrone Operationen auf verkettbare Weise zu behandeln und die Callback-Hölle zu vermeiden.
- async/await: Basierend auf Promises,
async/awaitEs bietet einen asynchronen Programmierstil, der näher an synchronem Code ist, wodurch asynchroner Code leichter zu verstehen und zu warten ist. - Ereignisgesteuerte Programmierung: Node.js unterstützt auch ereignisgesteuerte Programmierung, indem es Ereignisse abhört und auslöst, um asynchrone Operationen zu behandeln.
1. async/await verwenden
async/await ist syntaktischer Zucker, der in ES2017 eingeführt wurde und es ermöglicht, asynchrone Operationen bequemer zu handhaben und die Callback-Hölle zu vermeiden.
Beispiel
async function readFiles() {
try {
const data1 = await fs.readFile('file1.txt', 'utf8');
const data2 = await fs.readFile('file2.txt', 'utf8');
const data3 = await fs.readFile('file3.txt', 'utf8');
console.log('Daten aus allen Dateien:', data1, data2, data3);
} catch (err) {
console.error('Error reading files:', err);
}
}
readFiles();
. Promises verwenden
Promises sind eine weitere Möglichkeit, asynchrone Operationen zu handhaben. Du kannst Aufrufe an die then-Methode verketten, um verschachtelte Callbacks zu vermeiden.
Beispiel
fs.readFile('file1.txt', 'utf8')
.then(data1 => {
console.log('Daten aus Datei 1:', data1);
return fs.readFile('file2.txt', 'utf8');
})
.then(data2 => {
console.log('Daten aus Datei 2:', data2);
return fs.readFile('file3.txt', 'utf8');
})
.then(data3 => {
console.log('Daten aus Datei 3:', data3);
})
.catch(err => {
console.error('Error reading files:', err);
});
Callback-Funktionen sind eine grundlegende Möglichkeit, asynchrone Operationen in Node.js zu behandeln, aber mit zunehmender Komplexität der Anwendung wird das Problem der Callback-Hölle immer offensichtlicher. Durch die Verwendung von async/await oder Promises können die Lesbarkeit und Wartbarkeit des Codes erheblich verbessert werden.
Andere Erweiterungen