Ich benutze Node.js bei der Arbeit und finde es sehr mächtig. Ich würde gezwungen sein, ein Wort zu wählen, um Node.js zu beschreiben, und würde "interessant" sagen (was kein rein positives Adjektiv ist). Die Community ist lebendig und wächst. JavaScript kann trotz seiner Kuriositäten eine großartige Sprache zum Codieren sein. Und Sie werden täglich Ihr eigenes Verständnis von "Best Practice" und den Mustern von gut strukturiertem Code überdenken. Momentan fließt eine enorme Energie von Ideen in Node.js, und wenn Sie daran arbeiten, sind Sie all diesem Denken ausgesetzt - großartigem mentalem Gewichtheben.
Node.js in der Produktion ist definitiv möglich, aber weit entfernt von der "schlüsselfertigen" Bereitstellung, die in der Dokumentation anscheinend versprochen wird. Mit Node.js v0.6.x wurde "Cluster" in die Plattform integriert und stellt einen der wesentlichen Bausteine dar. Mein "Production.js" -Skript enthält jedoch immer noch ~ 150 Logikzeilen, um Dinge wie das Erstellen des Protokolls zu erledigen Verzeichnis, Recycling toter Arbeiter usw. Für einen "ernsthaften" Produktionsservice müssen Sie auch darauf vorbereitet sein, eingehende Verbindungen zu drosseln und all die Dinge zu erledigen, die Apache für PHP erledigt . Um fair zu sein, hat Ruby on Rails genau dieses Problem. Es wird über zwei komplementäre Mechanismen gelöst: 1) Ruby auf Schienen / Knoten setzen.Apache / Lighttd ). Der Webserver kann statische Inhalte effizient bereitstellen, auf die Protokollierung zugreifen, URLs neu schreiben, SSL beenden , Zugriffsregeln durchsetzen und mehrere Unterdienste verwalten. Bei Anforderungen, die den eigentlichen Knotendienst erfüllen, leitet der Webserver die Anforderung weiter. 2) Verwenden eines Frameworks wie Unicorn , das die Arbeitsprozesse verwaltet, sie regelmäßig recycelt usw. Ich habe noch kein Node.js-Serving-Framework gefunden, das vollständig gebacken zu sein scheint. es mag existieren, aber ich habe es noch nicht gefunden und verwende immer noch ~ 150 Zeilen in meiner handgerollten "Production.js".
Das Lesen von Frameworks wie Express lässt den Eindruck entstehen, dass die Standardpraxis darin besteht, alles über einen einzigen Node.js-Service zu bedienen ... "app.use (express.static (__ dirname + '/ public'))" . Für Dienste und Entwicklungen mit geringerer Auslastung ist dies wahrscheinlich in Ordnung. Sobald Sie jedoch versuchen, Ihren Service zeitaufwändig zu belasten und ihn rund um die Uhr laufen zu lassen, werden Sie schnell die Motive entdecken, die große Websites dazu veranlassen, gut gebackenen, gehärteten C-Code wie Nginx auf ihre Website zu setzen und alle zu verwalten der statischen Inhaltsanforderungen (... bis Sie ein CDN wie Amazon CloudFront einrichten )). Für eine etwas humorvolle und unverfroren negative Einstellung sehen Sie diesen Kerl .
Node.js findet auch immer mehr Nicht-Service-Anwendungen. Selbst wenn Sie etwas anderes zum Bereitstellen von Webinhalten verwenden, können Sie Node.js als Build-Tool verwenden, indem Sie Ihren Code mit npm- Modulen organisieren, mit Browserify in ein einzelnes Asset zusammenfügen und mit uglify-js für die Bereitstellung minimieren . Für den Umgang mit dem Web ist JavaScript eine perfekte Impedanzanpassung und häufig die einfachste Angriffsroute. Wenn Sie beispielsweise eine Reihe von JSON- Antwortnutzdaten durchsuchen möchten , sollten Sie mein Unterstrich-CLI- Modul verwenden, das Dienstprogramm für strukturierte Daten.
Für und Wider:
- Pro: Für einen Server-Typ war das Schreiben von JavaScript im Backend eine "Einstiegsdroge" zum Erlernen moderner UI-Muster. Ich habe keine Angst mehr, Client-Code zu schreiben.
- Pro: Neigt dazu, eine ordnungsgemäße Fehlerprüfung zu fördern (err wird von praktisch allen Rückrufen zurückgegeben, was den Programmierer dazu zwingt, damit umzugehen). Außerdem behandeln async.js und andere Bibliotheken das Paradigma "Fehler, wenn eine dieser Unteraufgaben fehlschlägt" viel besser als typischer synchroner Code )
- Pro: Einige interessante und normalerweise schwierige Aufgaben werden trivial - wie das Abrufen des Status von Aufgaben im Flug, die Kommunikation zwischen Mitarbeitern oder das Teilen des Cache-Status
- Pro: Riesige Community und jede Menge großartiger Bibliotheken basierend auf einem soliden Paketmanager (npm)
- Con: JavaScript hat keine Standardbibliothek. Sie sind so an das Importieren von Funktionen gewöhnt, dass es sich komisch anfühlt, wenn Sie JSON.parse oder eine andere integrierte Methode verwenden, für die kein npm-Modul hinzugefügt werden muss. Dies bedeutet, dass es von allem fünf Versionen gibt. Sogar die im "Kern" von Node.j enthaltenen Module haben fünf weitere Varianten, falls Sie mit der Standardimplementierung nicht zufrieden sind. Dies führt zu einer raschen Entwicklung, aber auch zu einer gewissen Verwirrung.
Im Vergleich zu einem einfachen One-Process-per-Request-Modell ( LAMP ):
- Pro: Skalierbar auf Tausende von aktiven Verbindungen. Sehr schnell und sehr effizient. Für eine Webflotte könnte dies eine 10-fache Reduzierung der Anzahl der erforderlichen Boxen im Vergleich zu PHP oder Ruby bedeuten
- Pro: Das Schreiben paralleler Muster ist einfach. Stellen Sie sich vor, Sie müssen drei (oder N) Blobs aus Memcached abrufen . Tun Sie dies in PHP ... haben Sie gerade Code geschrieben, der den ersten Blob abruft, dann den zweiten, dann den dritten? Wow, das ist langsam. Es gibt ein spezielles PECL- Modul, um dieses spezielle Problem für Memcached zu beheben. Was ist jedoch, wenn Sie einige Memcached-Daten parallel zu Ihrer Datenbankabfrage abrufen möchten? In Node.js ist es sehr natürlich, dass eine Webanforderung mehrere Dinge parallel ausführt, da das Paradigma asynchron ist.
- Con: Asynchroner Code ist grundlegend komplexer als synchroner Code, und die Lernkurve im Voraus kann für Entwickler schwierig sein, ohne genau zu verstehen, was gleichzeitige Ausführung tatsächlich bedeutet. Trotzdem ist es weitaus weniger schwierig, Multithread-Code mit Sperre zu schreiben.
- Con: Wenn eine rechenintensive Anforderung beispielsweise 100 ms lang ausgeführt wird, blockiert sie die Verarbeitung anderer Anforderungen, die im selben Node.js-Prozess verarbeitet werden ... AKA, Cooperative-Multitasking . Dies kann durch das Web Workers-Muster (Ausgliedern eines Unterprozesses zur Bewältigung der teuren Aufgabe) verringert werden. Alternativ können Sie eine große Anzahl von Node.js-Workern verwenden und nur einen einzelnen gleichzeitig bearbeiten lassen (immer noch ziemlich effizient, da kein Prozessrecycling erfolgt).
- Con: Das Ausführen eines Produktionssystems ist VIEL komplizierter als ein CGI- Modell wie Apache + PHP, Perl , Ruby usw. Nicht behandelte Ausnahmen führen zu einer Unterbrechung des gesamten Prozesses und erfordern eine Logik zum Neustart fehlgeschlagener Worker (siehe Cluster ). Module mit fehlerhaftem nativem Code können den Prozess zum Absturz bringen. Wenn ein Mitarbeiter stirbt, werden alle von ihm bearbeiteten Anforderungen gelöscht, sodass eine fehlerhafte API den Service für andere kohostierte APIs leicht beeinträchtigen kann.
Im Gegensatz zum Schreiben eines "echten" Dienstes in Java / C # / C (C? Wirklich?)
- Pro: Asynchron in Node.js zu arbeiten ist einfacher als Thread-Sicherheit an anderer Stelle und bietet wahrscheinlich einen größeren Nutzen. Node.js ist bei weitem das am wenigsten schmerzhafte asynchrone Paradigma, an dem ich je gearbeitet habe. Mit guten Bibliotheken ist es nur geringfügig schwieriger als das Schreiben von synchronem Code.
- Pro: Keine Multithreading / Locking-Fehler. Richtig, Sie investieren im Voraus in das Schreiben von ausführlicherem Code, der einen ordnungsgemäßen asynchronen Workflow ohne Blockierungsvorgänge ausdrückt. Und Sie müssen einige Tests schreiben und das Ding zum Laufen bringen (es ist eine Skriptsprache und fette Fingervariablennamen werden nur zur Zeit des Unit-Tests abgefangen). ABER, sobald Sie es zum Laufen bringen , ist die Oberfläche für Heisenbugs - seltsame Probleme, die sich nur einmal in einer Million Läufen manifestieren - diese Oberfläche nur viel viel kleiner . Die Steuern, die Node.js Code schreiben, werden stark in die Codierungsphase vorab geladen. Dann neigen Sie dazu, stabilen Code zu erhalten.
- Pro: JavaScript ist viel einfacher, um Funktionen auszudrücken. Es ist schwer, dies mit Worten zu beweisen, aber JSON , dynamische Typisierung, Lambda-Notation, prototypische Vererbung, leichte Module, was auch immer ... es braucht nur weniger Code, um die gleichen Ideen auszudrücken.
- Con: Vielleicht mögen Sie Codierungsdienste in Java wirklich, wirklich?
Eine weitere Perspektive zu JavaScript und Node.js finden Sie unter Von Java zu Node.js , einem Blogbeitrag über die Eindrücke und Erfahrungen eines Java-Entwicklers beim Erlernen von Node.js.
Module
Wenn der Knoten unter Berücksichtigung, bedenken Sie, dass Ihre Wahl von JavaScript - Bibliotheken werden DEFINE Ihre Erfahrungen. Die meisten Benutzer verwenden mindestens zwei, einen asynchronen Musterhelfer (Step, Futures, Async) und ein JavaScript-Zuckermodul ( Underscore.js ).
Helfer / JavaScript Sugar:
- Underscore.js - benutze dies. TU es einfach. Es macht Ihren Code schön und lesbar mit Sachen wie _.isString () und _.isArray (). Ich bin mir nicht sicher, wie Sie sonst sicheren Code schreiben könnten. Weitere Informationen zur erweiterten Befehlszeilenfunktion finden Sie in meiner eigenen Unterstrich-CLI .
Asynchrone Mustermodule:
- Schritt - eine sehr elegante Art, Kombinationen von seriellen und parallelen Aktionen auszudrücken. Meine persönliche Empfehlung. In meinem Beitrag erfahren Sie, wie der Schrittcode aussieht.
- Futures - viel flexibler (ist das wirklich eine gute Sache?), Um Bestellungen durch Anforderungen auszudrücken. Kann Dinge wie "a, b, c parallel starten. Wenn A und B fertig sind, starten Sie AB. Wenn A und C fertig sind, starten Sie AC." Diese Flexibilität erfordert mehr Sorgfalt, um Fehler in Ihrem Workflow zu vermeiden (z. B. niemals oder mehrmals aufrufen). Siehe Raynos 'Beitrag über die Verwendung von Futures (dies ist der Beitrag, der mich dazu gebracht hat, Futures zu "bekommen").
- Async - traditionellere Bibliothek mit einer Methode für jedes Muster. Ich begann damit vor meiner religiösen Bekehrung zum Schritt und der anschließenden Erkenntnis, dass alle Muster in Async in Schritt mit einem einzigen besser lesbaren Paradigma ausgedrückt werden könnten.
- TameJS - Geschrieben von OKCupid, ist es ein Precompiler, der ein neues Sprachprimativ "Warten" hinzufügt, um elegant serielle und parallele Workflows zu schreiben. Das Muster sieht toll aus, erfordert aber eine Vorkompilierung. Ich entscheide mich immer noch für diesen einen.
- StreamlineJS - Konkurrent von TameJS. Ich neige mich zu Tame, aber Sie können sich selbst entscheiden.
Um alles über die asynchronen Bibliotheken zu lesen, lesen Sie dieses Panel-Interview mit den Autoren.
Web Framework:
- Express Great Ruby on Rails-esk-Framework zum Organisieren von Websites. Es verwendet JADE als XML / HTML-Template-Engine, wodurch das Erstellen von HTML weitaus weniger schmerzhaft und sogar fast elegant wird.
- jQuery Obwohl jQuery technisch gesehen kein Knotenmodul ist, entwickelt es sich schnell zu einem De-facto-Standard für die clientseitige Benutzeroberfläche. jQuery bietet CSS-ähnliche Selektoren zum Abfragen von Gruppen von DOM-Elementen, die dann bearbeitet werden können (Gruppenhandler, Eigenschaften, Stile usw.). Entsprechend dem Bootstrap- CSS-Framework von Twitter , Backbone.js für ein MVC- Muster und Browserify.js , um alle Ihre JavaScript-Dateien zu einer einzigen Datei zusammenzufügen. Diese Module werden alle zu De-facto-Standards, daher sollten Sie sie zumindest überprüfen, wenn Sie noch nichts davon gehört haben.
Testen:
- JSHint - Muss verwendet werden; Ich habe das zunächst nicht benutzt, was jetzt unverständlich erscheint. JSLint fügt eine Reihe grundlegender Überprüfungen zurück, die Sie mit einer kompilierten Sprache wie Java erhalten. Nicht übereinstimmende Klammern, nicht deklarierte Variablen, Tippfehler in vielen Formen und Größen. Sie können auch verschiedene Formen des sogenannten "Anal-Modus" aktivieren, in dem Sie den Stil von Leerzeichen und so weiter überprüfen. Dies ist in Ordnung, wenn dies Ihre Tasse Tee ist. Der wahre Wert ergibt sich jedoch aus der sofortigen Rückmeldung der genauen Zeilennummer Sie haben ein schließendes ")" vergessen ... ohne Ihren Code ausführen und die beleidigende Zeile treffen zu müssen. „JSHint“ ist eine konfigurierbare Variante von Douglas Crockford ‚s JSLint .
- Mokka- Konkurrent zu Gelübden, die ich allmählich bevorzuge. Beide Frameworks beherrschen die Grundlagen gut genug, aber komplexe Muster lassen sich in Mocha leichter ausdrücken.
- Gelübde Gelübde sind wirklich sehr elegant. Und es druckt einen schönen Bericht (--spec) aus, der Ihnen zeigt, welche Testfälle bestanden / nicht bestanden wurden. Nehmen Sie sich 30 Minuten Zeit, um es zu lernen, und Sie können mit minimalem Aufwand grundlegende Tests für Ihre Module erstellen.
- Zombie - Kopfloses Testen auf HTML und JavaScript mit JSDom als virtuellem "Browser". Sehr mächtiges Zeug. Kombinieren Sie es mit Replay , um blitzschnelle deterministische Tests des Codes im Browser zu erhalten.
- Ein Kommentar zum "Nachdenken" über Tests:
- Das Testen ist nicht optional. Bei einer dynamischen Sprache wie JavaScript gibt es nur sehr wenige statische Überprüfungen. Wenn Sie beispielsweise zwei Parameter an eine Methode übergeben, die 4 erwartet, wird dies erst unterbrochen, wenn der Code ausgeführt wird. Ziemlich niedriger Balken zum Erstellen von Fehlern in JavaScript. Grundlegende Tests sind wichtig, um die Überprüfungslücke mit kompilierten Sprachen zu schließen.
- Vergessen Sie die Validierung, lassen Sie einfach Ihren Code ausführen. Für jede Methode ist mein erster Validierungsfall "nichts bricht", und das ist der Fall, der am häufigsten ausgelöst wird. Wenn Sie beweisen, dass Ihr Code ohne Auslösen ausgeführt wird, werden 80% der Fehler abgefangen und Ihr Code-Vertrauen wird so stark verbessert, dass Sie zurückkehren und die übersprungenen nuancierten Validierungsfälle hinzufügen.
- Fangen Sie klein an und brechen Sie die Trägheitsbarriere. Wir sind alle faul und unter Zeitdruck, und das Testen ist leicht als "zusätzliche Arbeit" anzusehen. Fangen Sie also klein an. Schreiben Sie Testfall 0 - laden Sie Ihr Modul und melden Sie den Erfolg. Wenn Sie sich dazu zwingen, genau so viel zu tun, ist die Trägheitsbarriere für Tests durchbrochen. Das sind <30 Minuten, um es zum ersten Mal zu tun, einschließlich des Lesens der Dokumentation. Schreiben Sie nun Testfall 1 - rufen Sie eine Ihrer Methoden auf und vergewissern Sie sich, dass "nichts kaputt geht", dh dass Sie keinen Fehler zurückerhalten. Testfall 1 sollte weniger als eine Minute dauern. Wenn die Trägheit weg ist, ist es einfach, Ihre Testabdeckung schrittweise zu erweitern.
- Entwickeln Sie jetzt Ihre Tests mit Ihrem Code. Lassen Sie sich nicht einschüchtern, wie der "richtige" End-to-End-Test mit Mock-Servern und all dem aussehen würde. Code beginnt einfach und entwickelt sich, um neue Fälle zu behandeln. Tests sollten auch. Wenn Sie Ihrem Code neue Fälle und neue Komplexität hinzufügen, fügen Sie Testfälle hinzu, um den neuen Code auszuführen. Wenn Sie Fehler finden, fügen Sie Überprüfungen und / oder neue Fälle hinzu, um den fehlerhaften Code abzudecken. Wenn Sie debuggen und das Vertrauen in einen Code verlieren, gehen Sie zurück und fügen Sie Tests hinzu, um zu beweisen, dass er das tut, was Sie denken. Erfassen Sie Zeichenfolgen von Beispieldaten (von anderen Diensten, die Sie aufrufen, Websites, die Sie kratzen, was auch immer) und geben Sie sie an Ihren Parsing-Code weiter. In einigen Fällen wurde die Validierung dort verbessert, und Sie erhalten einen äußerst zuverlässigen Code.
Lesen Sie auch die offizielle Liste der empfohlenen Node.js-Module. Das Node Modules Wiki von GitHub ist jedoch viel vollständiger und eine gute Ressource.
Um Node zu verstehen, ist es hilfreich, einige der wichtigsten Designoptionen zu berücksichtigen:
Node.js ist EVENT -BASIERT und ASYNCHRON / NON-BLOCKING. Ereignisse wie eine eingehende HTTP-Verbindung lösen eine JavaScript-Funktion aus, die ein wenig Arbeit erledigt und andere asynchrone Aufgaben wie das Herstellen einer Verbindung zu einer Datenbank oder das Abrufen von Inhalten von einem anderen Server startet. Sobald diese Aufgaben gestartet wurden, wird die Ereignisfunktion beendet und Node.js wird wieder in den Ruhezustand versetzt. Sobald etwas anderes passiert, z. B. die Herstellung der Datenbankverbindung oder der externe Server, der mit Inhalten antwortet, werden die Rückruffunktionen ausgelöst und mehr JavaScript-Code ausgeführt, wodurch möglicherweise noch mehr asynchrone Aufgaben (wie eine Datenbankabfrage) ausgelöst werden. Auf diese Weise verschachtelt Node.js gerne Aktivitäten für mehrere parallele Workflows und führt alle Aktivitäten aus, die zu einem beliebigen Zeitpunkt nicht blockiert sind. Aus diesem Grund leistet Node.js hervorragende Arbeit bei der Verwaltung von Tausenden von gleichzeitigen Verbindungen.
Warum nicht wie alle anderen auch nur einen Prozess / Thread pro Verbindung verwenden?In Node.js ist eine neue Verbindung nur eine sehr kleine Heap-Zuordnung. Das Hochfahren eines neuen Prozesses benötigt erheblich mehr Speicher, auf einigen Plattformen ein Megabyte. Die tatsächlichen Kosten sind jedoch die mit dem Kontextwechsel verbundenen Gemeinkosten. Wenn Sie 10 ^ 6 Kernel-Threads haben, muss der Kernel viel Arbeit leisten, um herauszufinden, wer als nächstes ausgeführt werden soll. Es wurde viel Arbeit in die Erstellung eines O (1) -Planers für Linux gesteckt, aber am Ende ist es viel effizienter, einen einzelnen ereignisgesteuerten Prozess zu haben, als 10 ^ 6 Prozesse, die um die CPU-Zeit konkurrieren. Unter Überlastungsbedingungen verhält sich das Multiprozessmodell außerdem sehr schlecht und es fehlen wichtige Verwaltungs- und Verwaltungsdienste, insbesondere SSHD (was bedeutet, dass Sie sich nicht einmal in die Box einloggen können, um herauszufinden, wie geschraubt es wirklich ist).
Node.js ist SINGLE THREADED und LOCK FREE . Node.js hat als sehr bewusste Designauswahl nur einen einzigen Thread pro Prozess. Aus diesem Grund ist es grundsätzlich unmöglich, dass mehrere Threads gleichzeitig auf Daten zugreifen. Somit werden keine Schlösser benötigt. Fäden sind hart. Wirklich sehr, sehr schwer. Wenn Sie das nicht glauben, haben Sie nicht genug Thread-Programmierung durchgeführt. Das richtige Sperren ist schwierig und führt zu Fehlern, die wirklich schwer zu finden sind. Durch das Eliminieren von Sperren und Multithreading verschwindet eine der schlimmsten Fehlerklassen. Dies könnte der größte Vorteil des Knotens sein.
Aber wie nutze ich meine 16-Core-Box?
Zwei Wege:
- Für große, schwere Rechenaufgaben wie die Bildcodierung kann Node.js untergeordnete Prozesse starten oder Nachrichten an zusätzliche Arbeitsprozesse senden. In diesem Entwurf muss ein Thread den Ablauf von Ereignissen und N Prozessen verwalten, die schwere Rechenaufgaben ausführen und die anderen 15 CPUs zerkauen.
- Um den Durchsatz auf einem Webservice zu skalieren, sollten Sie mehrere Node.js-Server auf einer Box ausführen, einen pro Kern, und dabei Cluster verwenden (Mit Node.js v0.6.x ersetzt das hier verlinkte offizielle "Cluster" -Modul die Learnboost-Version, die vorhanden ist eine andere API). Diese lokalen Node.js-Server können dann auf einem Socket konkurrieren, um neue Verbindungen zu akzeptieren und die Last über diese zu verteilen. Sobald eine Verbindung akzeptiert wird, wird sie eng an einen dieser gemeinsamen Prozesse gebunden. Theoretisch klingt das schlecht, aber in der Praxis funktioniert es recht gut und ermöglicht es Ihnen, die Kopfschmerzen beim Schreiben von thread-sicherem Code zu vermeiden. Dies bedeutet auch, dass Node.js eine hervorragende CPU-Cache-Affinität erhält und die Speicherbandbreite effektiver nutzt.
Mit Node.js können Sie einige wirklich mächtige Dinge tun, ohne ins Schwitzen zu geraten. Angenommen, Sie haben ein Node.js-Programm, das eine Vielzahl von Aufgaben ausführt, einen TCP- Port auf Befehle überwacht und einige Bilder codiert, was auch immer. Mit fünf Codezeilen können Sie ein HTTP-basiertes Webverwaltungsportal hinzufügen, das den aktuellen Status aktiver Aufgaben anzeigt. Dies ist EINFACH zu tun:
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end(myJavascriptObject.getSomeStatusInfo());
}).listen(1337, "127.0.0.1");
Jetzt können Sie eine URL eingeben und den Status Ihres laufenden Prozesses überprüfen. Wenn Sie einige Schaltflächen hinzufügen, haben Sie ein "Verwaltungsportal". Wenn Sie ein laufendes Perl / Python / Ruby-Skript haben, ist es nicht ganz einfach, nur ein Verwaltungsportal einzurichten.
Aber ist JavaScript nicht langsam / schlecht / böse / Spawn-of-the-Devil? JavaScript hat einige seltsame Kuriositäten, aber mit "den guten Teilen" gibt es dort eine sehr mächtige Sprache, und auf jeden Fall ist JavaScript DIE Sprache auf dem Client (Browser). JavaScript ist hier, um zu bleiben; Andere Sprachen zielen darauf als IL ab, und Weltklasse-Talente konkurrieren um die Entwicklung der fortschrittlichsten JavaScript-Engines. Aufgrund der Rolle von JavaScript im Browser wird ein enormer technischer Aufwand betrieben, um JavaScript schnell zum Laufen zu bringen. V8ist die neueste und beste Javascript-Engine, zumindest für diesen Monat. Die anderen Skriptsprachen werden sowohl in Bezug auf Effizienz als auch in Bezug auf Stabilität (Sie sehen sich an, Ruby) umgehauen. Und es wird nur besser, wenn große Teams bei Microsoft, Google und Mozilla an dem Problem arbeiten und um die beste JavaScript-Engine konkurrieren (es ist kein JavaScript- "Interpreter" mehr, da alle modernen Engines Tonnen von JIT ausführenKompilieren unter der Haube mit Interpretation nur als Fallback für einmal ausgeführten Code). Ja, wir alle wünschen uns, wir könnten einige der seltsameren JavaScript-Sprachoptionen korrigieren, aber es ist wirklich nicht so schlimm. Und die Sprache ist so verdammt flexibel, dass Sie wirklich kein JavaScript codieren, sondern Step oder jQuery - mehr als jede andere Sprache definieren die Bibliotheken in JavaScript die Erfahrung. Um Webanwendungen zu erstellen, müssen Sie ohnehin JavaScript kennen, sodass das Codieren auf dem Server eine Art Synergie von Fähigkeiten bietet. Ich habe mich nicht davor gefürchtet, Client-Code zu schreiben.
Wenn Sie JavaScript WIRKLICH hassen, können Sie außerdem syntaktischen Zucker wie CoffeeScript verwenden . Oder irgendetwas anderes, das JavaScript-Code erstellt, wie das Google Web Toolkit (GWT).
Apropos JavaScript, was ist ein "Abschluss"? - Eine ziemlich ausgefallene Art zu sagen, dass Sie Variablen mit lexikalischem Gültigkeitsbereich über Anrufketten hinweg beibehalten. ;) So was:
var myData = "foo";
database.connect( 'user:pass', function myCallback( result ) {
database.query("SELECT * from Foo where id = " + myData);
} );
// Note that doSomethingElse() executes _BEFORE_ "database.query" which is inside a callback
doSomethingElse();
Sehen Sie, wie Sie "myData" einfach verwenden können, ohne etwas Unangenehmes zu tun, wie es in einem Objekt zu verstecken? Und anders als in Java muss die Variable "myData" nicht schreibgeschützt sein. Diese leistungsstarke Sprachfunktion macht die asynchrone Programmierung weniger ausführlich und weniger schmerzhaft.
Das Schreiben von asynchronem Code wird immer komplexer sein als das Schreiben eines einfachen Single-Threaded-Skripts. Mit Node.js ist es jedoch nicht viel schwieriger und Sie erhalten neben der Effizienz und Skalierbarkeit für Tausende von gleichzeitigen Verbindungen viele Vorteile. ..