Vorwort
Das größte Highlight von NodeJS ist das ereignisgesteuerte, nicht blockierende E/A-Modell, wodurch NodeJs starke Funktionen für die Gleichzeitverarbeitungsfunktionen aufweisen und für das Schreiben von Netzwerkanwendungen sehr geeignet sind. Die meisten E/A -Operationen in NodeJs sind fast asynchron, dh die Ergebnisse unserer E/A -Operationen müssen im Grunde genommen in der Rückruffunktion verarbeitet werden, z. B. die folgende Funktion, in der der Inhalt der Datei liest:
Die Codekopie lautet wie folgt:
fs.readFile ('/etc/passwd', Funktion (err, data) {
Wenn (err) erröste;
console.log (Daten);
});
Was sollten wir also tun, wenn wir zwei Dateien lesen und den Inhalt dieser beiden Dateien zusammenführen? Die meisten Menschen, die nicht mit JS in Kontakt stehen, können dies tun:
Die Codekopie lautet wie folgt:
fs.readFile ('/etc/passwd', Funktion (err, data) {
Wenn (err) erröste;
fs.readFile ('/etc/passwd2', Funktion (err, data2) {
Wenn (err) erröste;
// Daten von Daten und Daten2 hier verarbeiten
});
});
Wenn Sie sich mit mehreren ähnlichen Szenarien befassen, wäre es nicht so, dass die Rückruffunktionen Schicht für Schicht verschachtelt sind? Dies ist es, was die Leute oft Pyramide oder Callback -Hölle (http://callbackhell.com/) zurückrufen, und es ist auch das schwierigste Problem für JS -Novice.
Diese Art von verschachteltem Kodex hat viele Probleme in die Entwicklung gebracht, hauptsächlich in:
1. Die Möglichkeit des Code wird schlechter
2. Schwierigkeiten
3.. Es ist schwierig zu überprüfen, nachdem eine Ausnahme eintritt
In diesem Artikel wird hauptsächlich vorgestellt, wie die oben genannten asynchronen Rückrufesprobleme elegant behandelt werden.
Primärlösung: rekursiv asynchrone Rückrufe verarbeiten
Wir können Rekursion als Ausführungssteuerungswerkzeug für den Code verwenden. Kapitulieren Sie die Vorgänge, die in eine Funktion ausgeführt werden müssen, und steuern Sie den Ausführungsprozess des Codes, indem Sie die Rückruffunktion rekursiv aufrufen. Lassen Sie uns ohne weiteres über Unsinn sprechen. Schauen wir uns den vorherigen Code an:
Die Codekopie lautet wie folgt:
var fs = fordert ('fs');
// Liste der zu verarbeitenden Dateien
var file = ['file1', 'file2', 'file3'];
Funktion parsefile () {
if (Dateien.length == 0) {
zurückkehren;
}
var file = files.shift ();
fs.ReadFile (Datei, Funktion (Err, Daten) {
// Dateidaten hier verarbeiten
ParseFile (); // Nach der Verarbeitung die nächste Datei durch rekursive Anruf verarbeiten
});
}
// Verarbeitung beginnen
ParseFile ();
Der obige Code hat die Dateien im Array wiederum als Beispiel verarbeitet, um den Ausführungsprozess der Steuerung des Codes über rekursive Mittel einzulegen.
Es ist gut, es auf einige einfache Szenarien anzuwenden, z. B.: Wir können diese Methode verwenden, indem wir die Daten in einem Array in der Datenbank speichern.
Rekursiv können einige einfache asynchrone Rückrufprobleme gelöst werden. Es erscheint jedoch nach wie vor machtlos, mit komplexen asynchronen Rückernständen umzugehen (z. B. die Synchronisierung der Ergebnisse mehrerer asynchroner Operationen).
Wunderschöner Punkt: Verwenden Sie Bibliotheken von Drittanbietern wie Async, Q, versprechen Sie, asynchrone Rückrufe zu behandeln
Um verschachtelte Rückrufe besser zu behandeln, können Sie einige Bibliotheken von Drittanbietern verwenden, die sich speziell mit Asynchron befassen. Wenn Sie die Fähigkeit haben, können Sie natürlich ein Hilfstool für asynchrone Verarbeitung selbst schreiben.
Die am häufigsten verwendeten Bibliotheken für den Umgang mit asynchroner Verarbeitung sind: asynchron, q und Versprechen. Async nach der NPMJS.org -Website ist die beliebteste. Ich habe Async schon einmal verwendet, und es ist in der Tat ziemlich bequem, und verschiedene asynchrone Verarbeitungssteuerungsströme sind gut implementiert.
Wir werden Async verwenden, um den Code zu verarbeiten, der zunächst zwei Dateien gleichzeitig liest, wie unten gezeigt:
Die Codekopie lautet wie folgt:
var async = fordert ('async')
, fs = erfordern ('fs');
async.parallel ([
Funktion (Rückruf) {
fs.readFile ('/etc/passwd', Funktion (err, data) {
if (err) callback (err);
Rückruf (NULL, Daten);
});
},
Funktion (Rückruf) {
fs.readFile ('/etc/passwd2', Funktion (err, data2) {
if (err) callback (err);
Rückruf (null, data2);
});
}
],
Funktion (err, Ergebnisse) {
// Verarbeitungsdaten von Daten und Daten2 hier verarbeiten, und der Inhalt jeder Datei wird aus den Ergebnissen erhalten
});
Durch das asynchronisierte Modul kann der asynchrone Ausführungsprozess gut kontrolliert werden, was auch das Problem der geschichteten Rückrufe lösen kann. Der Code ist klarer als zuvor, kann aber immer noch nicht von der Rückruffunktion getrennt werden.
Denken Sie darüber nach, es wäre großartig, wenn Sie mit Asynchron handeln können, ohne Rückruffunktionen zu verwenden. Lassen Sie uns als nächstes über die Verwendung der neuen Funktionen von ES6 sprechen, um dieses Ziel zu erreichen.
Eleganter Punkt: Umarmen Sie ES6, ersetzen Sie die Rückruffunktionen und lösen
Übrigens hat die ECMascript Harmony (ES6) JS viele neue Funktionen vorgelegt. Studenten, die nicht viel über ES6 wissen, können selbst einen Baidu -Blick aufnehmen.
Um die neuen Funktionen von ES6 in NodeJs zu verwenden, müssen Sie v0.11.x oder höher verwenden.
In diesem Artikel wird die Verwendung der Generatorfunktion anstelle von Rückruffunktionen eingeführt. Kennt man nichts über Generator? Sie können es hier überprüfen.
Hier verwenden wir zwei Module CO und Thunkify und verwenden den Befehl npm install, um ihn zu installieren.
Nehmen Sie das am Anfang dieses Artikels genannte Problem als Beispiel. Der Beispielcode, der die Generatorfunktion verwendet, lautet wie folgt:
Die Codekopie lautet wie folgt:
var fs = erfordern ('fs')
, co = fordert ('co')
, thunkify = fordert ('thunkify');
var readFile = thunkify (fs.readfile);
co (function *() {
var test1 = Ertragsresadfile ('test1.txt');
var test2 = Rendite Readfile ('test2.txt');
var test = test1.toString () + Test2.ToString ();
console.log (test);
}) ();
Es ist auch sehr einfach, Ausnahmen im Code zu bewältigen. Machen Sie es einfach so:
Die Codekopie lautet wie folgt:
versuchen {
var test1 = Ertragsresadfile ('test1.txt');
} catch (e) {
// Ausnahmen hier behandeln
}
Ist diese Art von Code viel eleganter? Ist es nicht toll, asynchron wie das Schreiben von Synchroncode zu handhaben?
Der beliebteste Rahmen für die Webentwicklung im Bereich NodeJS ist ausdrücklich. Es ist erwähnenswert, dass das Kernmitglied von Express TJ, The Great Master of Express, ein neues Web -Framework geleitet hat - KOA, das behauptet, die nächste Generation von Webentwicklungsrahmen zu sein. KOA verwendet die Funktion des ES6 -Generators wirklich, um zu vermeiden, dass wir bei der Entwicklung des Websystems in Schichten von Rückrufen fallen.
Zusammenfassen
Zitieren