web-dev-qa-db-de.com

Warum ist node.js asynchron?

Niemand hat das wirklich gefragt (von all den 'Vorschlägen', die ich bekomme und auch von der Suche, bevor ich hier gefragt habe).

Warum ist node.js asynchron?

Woraus ich nach einigen Recherchen geschlossen habe:

Sprachen wie PHP und Python) sind Skriptsprachen (ich könnte mich in Bezug auf die tatsächlichen Sprachen, die Skriptsprachen sind, irren), während JavaScript dies nicht ist ergibt sich aus der Tatsache, dass JS nicht kompiliert?)

Node.js wird auf einem einzelnen Thread ausgeführt, während Skriptsprachen mehrere Threads verwenden.

Asynchron bedeutet zustandslos und dass die Verbindung dauerhaft ist, während synchron das (fast) Gegenteil ist.

Vielleicht ist die Antwort irgendwo oben angegeben, aber ich bin mir immer noch nicht sicher.

Meine zweite und letzte Frage zu diesem Thema lautet:

Könnte JavaScript in eine synchrone Sprache umgewandelt werden?

PS. Ich weiß, dass einige von Ihnen fragen werden, warum Sie JS synchron machen möchten. in deinen Antworten, aber die Wahrheit ist, dass ich es nicht tue. Ich stelle nur diese Art von Fragen, weil ich sicher bin, dass es mehr Leute gibt als nur mich, die über solche Fragen nachgedacht haben.

47
Joe

Node.js wird auf einem einzelnen Thread ausgeführt, während Skriptsprachen mehrere Threads verwenden.

Nicht technisch. Node.js verwendet mehrere Threads, jedoch nur einen Ausführungsthread. Die Hintergrund-Threads sind für den Umgang mit IO) vorgesehen, damit die gesamte asynchrone Funktionalität funktioniert. Ein effizienter Umgang mit Threads ist eine große Herausforderung. Daher ist es die nächstbeste Option, eine Ereignisschleife auszuführen, damit Code ausgeführt werden kann Ausführen, während Hintergrundthreads auf E/A blockiert sind.

Asynchron bedeutet zustandslos und dass die Verbindung dauerhaft ist, während synchron das (fast) Gegenteil ist.

Nicht unbedingt. Sie können den Status in einem asynchronen System ziemlich einfach beibehalten. In Javascript können Sie beispielsweise bind() verwenden, um ein this an eine Funktion zu binden, wodurch der Status explizit beibehalten wird, wenn die Funktion zurückgibt:

function State() {
    // make sure that whenever doStuff is called it maintains its state
    this.doStuff = this.doStuff.bind(this);
}
State.prototype.doStuff = function () {
};

Asynchron bedeutet, nicht auf den Abschluss einer Operation zu warten, sondern stattdessen einen Listener zu registrieren. Dies geschieht die ganze Zeit in anderen Sprachen, insbesondere wenn Eingaben vom Benutzer akzeptiert werden müssen. Beispielsweise blockieren Sie in einer Java GUI nicht das Warten auf das Drücken einer Taste durch den Benutzer, sondern registrieren einen Listener in der GUI.

Meine zweite und letzte Frage zu diesem Thema lautet:

Könnte JavaScript in eine synchrone Sprache umgewandelt werden?

Technisch sind alle Sprachen synchron, sogar Javascript. In einem asynchronen Design funktioniert Javascript jedoch viel besser, da es für Single-Threading konzipiert wurde.

Grundsätzlich gibt es zwei Arten von Programmen:

  • CPU-gebunden - der einzige Weg, um es schneller zu machen, ist, mehr CPU-Zeit zu bekommen
  • E/A-Grenzen erfordern viel Zeit für das Warten auf Daten, sodass ein schnellerer Prozessor keine Rolle spielt

Videospiele, Number Cruncher und Compiler sind CPU-gebunden, während Webserver und GUIs im Allgemeinen IO) gebunden sind. Javascript ist relativ langsam (aufgrund seiner Komplexität), sodass dies nicht möglich wäre in einem CPU-gebundenen Szenario zu konkurrieren (Vertrauen Sie mir, ich habe meinen fairen Anteil an CPU-gebundenem Javascript geschrieben).

Anstatt in Klassen und Objekten zu codieren, bietet sich Javascript an, einfache Funktionen zu codieren, die aneinander gereiht werden können. Dies funktioniert bei asynchronem Design sehr gut, da Algorithmen so geschrieben werden können, dass Daten bei Eingang inkrementell verarbeitet werden. IO (insbesondere Netzwerk-IO) ist sehr langsam, sodass zwischen Paketen einige Zeit vergeht von Dateien.

Beispiel

Angenommen, Sie haben 1000 Live-Verbindungen, von denen jede ein Paket pro Millisekunde liefert, und die Verarbeitung jedes Pakets dauert 1 Mikrosekunde (sehr vernünftig). Angenommen, jede Verbindung sendet 5 Pakete.

In einer synchronen Singlethread-Anwendung wird jede Verbindung in Reihe behandelt. Die Gesamtzeit beträgt (5 * 1 + 5 * .001) * 1000 Millisekunden oder ~ 5005 Millisekunden.

In einer asynchronen Single-Thread-Anwendung wird jede Verbindung parallel verarbeitet. Da jedes Paket 1 Millisekunde dauert und die Verarbeitung jedes Pakets 0,001 Millisekunden dauert, können wir jedes Verbindungspaket zwischen Paketen verarbeiten. Unsere Formel lautet also: 1000 * 0,001 + 5 * 1 Millisekunden oder ~ 6 Millisekunden.

Die traditionelle Lösung für dieses Problem bestand darin, mehr Threads zu erstellen. Dies löste das Problem IO), aber als die Anzahl der Verbindungen anstieg, stieg auch die Speichernutzung (Threads kosteten viel Speicher) und die CPU-Auslastung (Multiplexen von 100 Threads auf einen Kern ist schwieriger als 1) Thread auf 1 Kern).

Es gibt jedoch Nachteile. Wenn Ihre Webanwendung auch einige schwere Zahlen verarbeiten muss, sind Sie SOL während Sie Zahlen verarbeiten, müssen die Verbindungen warten. Durch das Threading wird dies behoben, da das Betriebssystem ausgelagert werden kann Ihre CPU-intensive Aufgabe, wenn Daten für einen Thread bereit sind, der auf E/A wartet. Außerdem ist node.js an einen einzelnen Kern gebunden, sodass Sie Ihren Mehrkernprozessor nur dann nutzen können, wenn Sie mehrere Instanzen und Proxy-Anforderungen starten .

51
beatgammit

Javascript kompiliert nicht in irgendetwas. Es wird zur Laufzeit "ausgewertet", genau wie PHP & Ruby. Daher ist es eine Skriptsprache wie PHP/Ruby. (Der offizielle Name ist eigentlich ECMAScript.).

Das 'Modell', an dem Node) festhält, unterscheidet sich ein wenig von PHP/Ruby. Node.js verwendet eine 'Ereignisschleife' (den einzelnen Thread) mit dem einzigen Ziel, Netzwerkanforderungen entgegenzunehmen und Sie werden sehr schnell verarbeitet, und wenn aus irgendeinem Grund eine Operation auftritt, die eine Weile dauert (API-Anforderung, Datenbankabfrage - im Grunde alles, was IO (Eingabe/Ausgabe) betrifft), wird dies an einen Worker-Thread im Hintergrund weitergeleitet und dann abgebrochen Wenn der Worker-Thread auf den Abschluss der langen Aufgabe wartet, werden die Ergebnisse in der Hauptereignisschleife erfasst und weiter verarbeitet.

PHP/Ruby nach einem Threading-Modell. Für jede eingehende Netzwerkanforderung dreht der Anwendungsserver im Wesentlichen einen isolierten Thread oder Prozess, um die Anforderung zu verarbeiten. Dies lässt sich nicht sehr gut skalieren und der Ansatz von Node wird als eine seiner Kernstärken im Vergleich zu diesem Modell bezeichnet.

Asynchron bedeutet zustandslos und dass die Verbindung dauerhaft ist, während synchron das (fast) Gegenteil ist.

Nein. Die synchronen Anweisungen werden von Anfang bis Ende in einer natürlichen Reihenfolge ausgeführt. Asynchrone Anweisungen bedeuten, dass, wenn ein Schritt im Ablauf eines Programms relativ lange dauert, das Programm die Ausführung von Operationen fortsetzt und nach Abschluss einfach zu dieser Operation zurückkehrt.

Könnte JavaScript in eine synchrone Sprache umgewandelt werden?

Bestimmte Vorgänge in JavaScript sind synchron. Andere sind asynchron. Beispielsweise:


Sperrvorgänge:

for(var k = 0; k < 1; k = k - 1;){
  alert('this will quickly get annoying and the loop will block execution')
alert('this is blocked and will never happen because the above loop is infinite');

Asynchron:

jQuery.get('/foo', function (result) { alert('This will occur 2nd, asynchronously'); });
alert('This will occur 1st. The above operation was skipped over and execution continued until the above operation completes.');
32
Casey Flynn

Könnte JavaScript in eine synchrone Sprache umgewandelt werden?

Javascript ist keine "asynchrone Sprache"; Stattdessen hat node.js viele asynchrone APIs. Asynchronität ist eine Eigenschaft der API und nicht der Sprache. Die Leichtigkeit, mit der Funktionen in JavaScript erstellt und weitergegeben werden können, erleichtert die Übergabe von Rückruffunktionen. Dies ist eine Möglichkeit, den Steuerungsfluss in einer asynchronen API zu verarbeiten. An Javascript ist jedoch nichts inhärent asynchron. Javascript kann problemlos synchrone APIs unterstützen.

Warum ist node.js asynchron?

Node.js bevorzugt asynchrone APIs, da es sich um Single-Thread-APIs handelt. Dies ermöglicht eine effiziente Verwaltung der eigenen Ressourcen, erfordert jedoch, dass lang laufende Vorgänge nicht blockiert werden und dass asynchrone APIs eine Möglichkeit darstellen, den Datenfluss mit vielen nicht blockierenden Vorgängen zu steuern.

20
Trevor Dixon