Eine Diskussion über Knotenmodule ist unvollständig,
ohne über Callbacks und Fehlerbehandlung zu sprechen.
Was sind Callbacks und warum sind sie für die
Unterstützung asynchroner Berechnungen wichtig, die sehr
nützlich ist, wenn wir Node.js Anwendungen schreiben?
Wie wird die Fehlerbehandlung in Node-Anwendungen durchgeführt?
Lassen Sie uns kurz darüber in dieser Vorlesung sprechen.
Bevor wir über Knotenmodule und Callbacks sprechen,
müssen wir zwei herausragende Funktionen über die JavaScript-Sprache selbst verstehen.
In erster Linie unterstützt JavaScript, was als erstklassige Funktionen bezeichnet wird.
Was meinen wir mit erstklassigen Funktionen?
Ist, dass eine Funktion wie jede andere Variable behandelt werden kann.
Und daher können Funktionen als
Parameter innerhalb von Funktionsaufrufen an andere Funktionen übergeben werden.
Und das ermöglicht es uns im Wesentlichen, Funktionen als Callback-Funktionen zu senden, die
von einem anderen Node-Modul aufgerufen werden können, um etwas Arbeit zu erledigen.
Dann schauen Sie sich an, wie dies sehr nützlich ist, um Callbacks in Node.js zu unterstützen.
Der zweite Aspekt von JavaScript ist die Unterstützung für Closures.
Was meinen wir mit Closures?
Vor allem, wenn Sie mit funktionalen Programmiersprachen vertraut sind,
verstehen Sie, wie die Schließung funktioniert.
Eine Funktion, die in einer anderen Funktion definiert ist,
erhält automatisch Zugriff auf die Variablen, die in der äußeren Funktion deklariert werden.
Also, selbst wenn die äußere Funktion abgeschlossen ist,
wenn die innere Funktion später ausgeführt wird, hat die innere Funktion immer noch Zugriff auf
die Werte der Variablen innerhalb dieser äußeren Funktion.
Und das wird wieder
sehr effektiv verwendet, wenn wir Callbacks in Node-Anwendungen verwenden.
Wenn Sie an die Standardmethode des Schreibens von Anwendungen gewöhnt sind,
sind Sie mit der synchronen Berechnung vertraut, bei der Sie
eine Berechnung als eine Reihe von Schritten angeben, die nacheinander durchgeführt werden sollen.
Nun, wenn Sie Ihre Berechnung wie folgt organisieren,
wie auf der linken Seite der Folie hier gezeigt,
haben wir Berechnung eins, gefolgt von einer lang laufenden Berechnung,
gefolgt von Berechnung zwei und Berechnung drei.
Nehmen wir in dieser Anordnung an, dass Berechnung zwei von
der lang laufenden Berechnung abhängt, die ihre Arbeit beendet,
dann macht es Sinn, dass Berechnung zwei warten muss, bis
die lange laufende Berechnung abgeschlossen ist, bevor sie ausgeführt wird.
Nun, wir könnten noch ein Stück Arbeit
zu tun haben, die durch Berechnung drei definiert ist.
Berechnung drei kann in keiner Weise abhängig von der Berechnung zwei sein,
oder der lang laufenden Berechnung, die abgeschlossen werden muss, bevor sie ausgeführt wird.
Also,
wenn wir in diesem Fall synchrone Ausführung dieser Berechnung durchführen,
dann wird die Berechnung drei stecken bleiben,
obwohl es keine Möglichkeit ist, abhängig von der Fertigstellung entweder der Berechnung zwei
oder der lang laufenden Berechnung.
So wird die Menge der Arbeit, die durch Berechnung drei zu erledigen ist,
verzögert werden, weil es keinen eigenen Grund gibt, oder?
Stattdessen wird aufgrund von etwas verzögert, das ihm in der Reihenfolge der Berechnung vorausgeht.
Nun, asynchrone Berechnung, können wir diese Arbeit
so neu anordnen, dass die Berechnung eins, wenn sie abgeschlossen ist,
diese lang laufenden Berechnungen hervorbringen kann, die unabhängig hinter den Kulissen durchgeführt werden,
und da die Berechnung zwei von der lang laufenden Berechnung abhängt,
dann kann die Berechnung zwei ausgeführt werden, wenn die lange laufende Berechnung beendet ist.
Nun, dies befreit die Berechnung drei, um fortzufahren,
direkt nach der Berechnung eins abgeschlossen ist.
Diese Art der Anordnung stellt also
sicher, dass die Berechnung drei viel schneller beendet wird
, als hinter der lang laufenden Berechnung und der Berechnung zwei stecken bleibt.
Dieser Ansatz der Neuanordnung Ihrer Arbeit ist daher sehr nützlich, besonders
wenn Sie eine lange laufende Berechnung haben, insbesondere wenn Sie eine
E/A-gebundene Berechnung durchführen müssen.
In diesem Fall können Sie die I/O-gebundene Berechnung auslösen,
und wenn dies abgeschlossen ist,
kann alles, was danach getan werden muss, als Rückruf an sie gesendet werden.
Die Berechnung zwei wird also in
einen Callback umgewandelt und dann der lang laufenden Berechnung übergeben.
Wenn das seine Arbeit abgeschlossen ist,
ruft es die Funktion zurück, die innerhalb des Callbacks eingeschlossen ist.
Dies wird also sehr effektiv von Node.js genutzt, um
die Berechnung innerhalb unserer Node-Anwendungen neu anzuordnen.
Nun, das ist sehr,
sehr nützlich, wenn wir uns die Art und Weise ansehen, wie Node.js selbst läuft.
Wie wir erkennen,
ist Node.js in einer einzelnen Thread-Ereignisschleife organisiert.
Diese Single-Thread-Ereignisschleife
nimmt im Grunde Anfragen auf, wie sie eingehen und sie nacheinander ausführen.
Immer wenn eine E/A-Anforderung
erzeugt werden muss, wird die E/A-Anforderung ausgelöst
und jede Arbeit, die nach Abschluss der E/A-Anforderung ausgeführt werden muss,
wird in einen Callback eingeschlossen.
Wenn die E/A-Anforderung abgeschlossen
ist, wird der Callback in die Anforderungswarteschlange gesetzt,
und der Rückruf wird danach
von der Ereignisschleife behandelt.
Die Ereignisschleife ist also eine kontinuierlich laufende Schleife
, die im Grunde Anfragen aus der Anforderungswarteschlange aufnimmt
und sie dann nacheinander bedient.
Wenn Sie also darüber nachdenken,
erkennen Sie, dass Node.js ein einzelner Thread ist,
aber gleichzeitig
ist es in der Lage, viel schnellere Abschlussrate der Arbeit zu erreichen,
einfach wegen der vernünftigen Verwendung von Callbacks
und der asynchronen Ausführung von E/A-Anfragen,
wie für Datei Zugriffe oder eine Datenbank
oder eine lange laufende Verarbeitung, die unabhängig hinter den Kulissen durchgeführt werden kann.
Nun
ist die Art und Weise, wie die Ereignisschleife Node.js all dies behandelt, dass die Ereignisschleife in einer Folge von Phasen angeordnet ist.
Wie Sie in dem hier gezeigten Diagramm sehen,
umfassen die Phasen Timerhandhabung,
I/O-Callback-Behandlung, dann haben Sie Leerlauf, Vorbereitung,
dann die Abfrage, in der die eingehenden Anfragen für Verbindungen oder Daten behandelt werden,
und dann die Prüfphase
und schließlich die Callback-Phase schließen.
Nun, einige Details darüber, was in jeder dieser Phasen getan wird, sind auf der rechten Seite aufgeführt.
In der Timer-Phase
verarbeitet die Ereignisschleife alles, was durch die
Funktion setTimeout () in JavaScript ausgelöst wird.
Die I/O-Callbacks werden ausgeführt,
fast alle Callbacks, die
nach einer E/A-Anforderung ausgeführt werden, werden von der I/O-Callback-Warteschlange behandelt.
Jede dieser Phasen behält also ihre eigene separate Warteschlange,
und die Ereignisschleife Node.js nimmt Anforderungen aus jeder dieser Warteschlangen auf und behandelt sie.
Die, Leerlauf, Vorbereitung, ist für den internen Gebrauch durch Node.js gedacht.
In der Umfrage werden neue E/A-Ereignisse abgerufen, die behandelt werden sollen, und vielleicht
die Anfragen, die von außen eingehen.
Die Close-Callback-Phase behandelt alle Socket Closures, die behandelt werden müssen, und so weiter.
Jetzt müssen wir uns nicht zu sehr um
all diese Details kümmern, wenn wir wirklich eine Node.js Anwendung schreiben müssen.
Wenn erforderlich, werden wir einige dieser Details betrachten, wie und wann
es wichtig ist, um zu verstehen, wie unsere Node-Anwendung funktioniert.
Aber im Moment gibt Ihnen dies eine große Übersicht darüber,
wie die Ereignisschleife Node.js behandelt wird.
Es genügt zu sagen, dass dies ausreichend Informationen für uns ist, um
die Node-Anwendungen zu verstehen und wie sie für den Moment funktionieren.
Wenn Sie mehr Details wissen möchten,
dann habe ich Ihnen einen Link zu einer detaillierten Beschreibung in der Node.js
Dokumentation gegeben, die die Ereignisschleife ausführlicher erläutert.
Mit diesem schnellen Verständnis von Node,
Callbacks und Fehlerbehandlung
werden wir zu der Übung übergehen,
wo wir untersuchen, wie eine Node-Anwendung mit Callbacks geschrieben
werden kann und wie Fehler innerhalb einer Node-Anwendung behandelt werden können.
Wir werden die wiederholte Verwendung dieses Musters in nachfolgenden Übungen
und nachfolgenden Lektionen speziell sehen,
wenn wir Express betrachten,
und wie wir serverseitige Anwendungen mit Express
im späteren Teil dieses Kurses im Detail erstellen.