Top 5 Fehler, die Knotenentwickler machen

Node ist eine fantastische Plattform zum Schreiben von Backends. Außer wenn Sie die Dinge nicht richtig machen.


Je nachdem, auf welcher Seite des Zauns Sie sich gerade befinden, ist Node entweder das Beste oder das Schlechteste, was der Webentwicklungswelt passieren kann. Ungeachtet der Meinungen kann die Popularität von Node nicht bestritten werden. Es wurde immer schneller populär, als irgendjemand erwartet hatte, sogar sein Schöpfer (er sagte es in einem ansonsten pessimistischen Interview)!

Zum Zeitpunkt des Schreibens ist dies die Standardplattform zum Starten neuer Apps. Ich gebe zu, dass dies häufig auf die Herdenmentalität zurückzuführen ist. Der Nettoeffekt ist jedoch, dass es in Node mehr Jobs, mehr Geld und aufregendere Projekte gibt als in anderen traditionellen Skriptsprachen.

Leider ist es zu einem Punkt gekommen, dass Node meine erste Empfehlung ist, wenn mich jemand bittet, ihm einen Startstapel für die Webentwicklung oder neue Startup-Produkte zu empfehlen, obwohl ich mich mit PHP und Laravel auskenne.

Wenn ich das Geschwätz ein wenig fortsetzen darf (was werde ich sein, da ich derjenige bin, der schreibt?), Haben Node-Hasser einen Punkt, an dem sie sagen, dass ihr Lieblings-Web-Stack die Dinge genauso gut kann wie Node, aber Das Gegenteil ist auch wahr. Und dann gibt es asynchrone Programmierungen und Ereignisse, die vom ersten Tag an in Node eingebrannt wurden, und andere Ökosysteme versuchen nun verzweifelt zu kopieren.

Heute haben wir asynchrone Optionen in PHP und Python, aber leider ist der Kern der vorhandenen, beliebten Bibliotheken rein synchron, sodass es fast so ist, als würden Sie gegen das System kämpfen. Aber genug für einen Tag. ��

Wenn Sie ein Node-Entwickler sind (Anfänger oder Vertraute), machen Sie wahrscheinlich einen dieser großen Fehler, die sich negativ auf Ihre Anwendung auswirken. Dies kann daran liegen, dass Sie nicht mit einer bestimmten Methode vertraut sind, um die Dinge in Node besser zu machen, oder daran, dass Sie einfach Gewohnheiten aus einem anderen Ökosystem übernommen haben.

Die Ereignisschleife wird nicht beachtet

Wenn eine Person zu Node migriert, liegt dies teilweise daran, dass sie Geschichten darüber gehört hat, wie LinkedIn mithilfe von Node skaliert, oder dass sie Benchmarks gesehen haben, die zeigen, wie Node Kreise um PHP, Ruby usw. herumführt, wenn es darum geht, Anforderungen pro Sekunde zu bearbeiten oder zu bearbeiten Socket-Verbindungen öffnen.

Also bauen sie ihre App und erwarten die gleichen explosiven Reaktionszeiten, von denen sie geträumt haben – außer dass nichts in der Nähe davon passiert.

Einer der Hauptgründe dafür ist, dass die Ereignisschleife nicht richtig verstanden wird. Betrachten Sie den folgenden Code, der eine Reihe von Büchern aus der Datenbank abruft und diese dann nach der Gesamtzahl der Seiten sortiert:

db.Library.get (libraryId, function (err, library) {
let books = library.books;
books.sort (Funktion (a, b) {
a.pages zurückgeben < b.pages? -1: 1
});
});

Ich bin damit einverstanden, dass dieser Code mit dem Array sortierter Bücher nichts zu tun hat, aber das ist hier nicht der Punkt. Der Punkt ist, dass solch ein unschuldig aussehender Code ausreicht, um die Ereignisschleife zu sprengen, sobald Sie anfangen, sich mit einer nicht trivialen Anzahl von Büchern zu befassen.

Der Grund ist, dass die Ereignisschleife nicht blockierende E / A ausführen soll. Ein gutes Beispiel ist das eines Pizzaverpackers in einer Pizzeria – die Person ist darauf spezialisiert, die Pizza zu schneiden, Abdeckungen in Lieferboxen zu falten, die Pizza einzulegen, die richtigen Etiketten anzubringen und sie dem Lieferboten zu schieben.

Erstaunlich, richtig? Genau wie Node!

Quelle: stackoverflow.com

Aber überlegen Sie, was passieren wird, wenn diese Person auch die Gewürze mischen, vorbereiten und verpacken muss. Je nachdem, wie kompliziert der Prozess ist, wird die Verpackungsrate für Pizza auf ein Drittel gesenkt oder kommt sogar zum Stillstand.

Dies ist das, was wir unter Aufgaben verstehen, die „blockieren“ – solange Node lediglich Informationen weitergeben muss, ist dies sehr schnell und idealerweise die beste Option, aber sobald umfangreiche Berechnungen erforderlich sind, stoppt es und alles sonst muss warten. Dies liegt daran, dass die Ereignisschleife Single-Threaded ist (weitere Details) Hier.)

Führen Sie also keine Berechnungen innerhalb der Ereignisschleife durch, egal wie wichtig sie sind. Ich meine, das Hinzufügen von Zahlen und das Ermitteln von Durchschnittswerten ist in Ordnung, aber große Datenmengen lassen Ihre Node-App crawlen.

Ich hoffe, dass der asynchrone Code zusammenarbeitet

Betrachten Sie dieses sehr einfache Knotenbeispiel, das Daten aus einer Datei liest und anzeigt:

const fs = require (‘fs’);

let content = fs.readFile (‘secret.txt’, (err, data) => {
Daten zurückgeben;
});

console.log (‘Dateiinhalt sind:’);
console.log (Inhalt);

Wenn Sie mit klassischen Sprachen (wie PHP, Python, Perl, Ruby, C ++ usw.) vertraut sind, wenden Sie den gesunden Menschenverstand an, dass der variable Inhalt nach der Ausführung dieses Codes den Inhalt der Datei enthält. Folgendes passiert jedoch, wenn Sie den Code tatsächlich ausführen:

Wir werden undefiniert (). Das liegt daran, dass Sie sich zwar sehr für Node interessieren, sich aber nicht für Sie interessieren (es soll ein Witz sein! Bitte spammen Sie hier keine Hasskommentare ��). Unsere Aufgabe ist es, seine asynchrone Natur zu verstehen und damit zu arbeiten. readFile () ist eine asynchrone Funktion. Sobald sie aufgerufen wird, gibt die Node-Ereignisschleife die Arbeit an die Dateisystemkomponente weiter und fährt fort.

Es kehrt später zu der Funktion zurück, wenn die Datei gelesen wurde, aber zu diesem Zeitpunkt wird der Inhalt wie eine nicht initialisierte Variable behandelt und enthält daher undefiniert. Der richtige Weg besteht darin, die Dateidaten innerhalb der Rückruffunktion zu verarbeiten, aber ich kann nicht auf weitere Details eingehen, da dies keine ist Knoten-Tutorial. ��

Rückruf, der den Rückruf aufruft, der den Rückruf aufruft, der anruft . . .

JavaScript ist der funktionalen Programmierung näher als jede andere ältere Mainstream-Sprache (alles gesagt und getan, es ist mein Favorit, wenn es um objektorientiertes Design und funktionale Funktionen geht – ich habe es über Python, PHP, Perl, Java und sogar Ruby, wenn es darum geht, „unterhaltsamen“ Code zu schreiben).

Das heißt, Funktionen erhalten mehr Bürgerrechte als in anderen Sprachen. Kombinieren Sie dies mit der Tatsache, dass asynchroner Code eine Rückruffunktion bietet, und wir erhalten ein Rezept für eine Katastrophe namens Callback Hell.

Hier ist ein Beispiel für einen Elektronencode, den ich auf Quora gefunden habe. Was glaubst du, macht es??

var options;

erfordern (‘Elektron’). app.once (
‘bereit’,

function () {

options = {
Rahmen: falsch,
Höhe: 768,
Breite: 1024,
x: 0,
y: 0
};

options.BrowserWindow = erfordern (‘Elektron’). BrowserWindow;
options.browserWindow = neue Optionen.BrowserWindow (Optionen);
options.browserWindow.loadURL (‘http://electron.atom.io’);
options.browserWindow.webContents.once (
‘Did-Stop-Loading’,

function () {
options.browserWindow.capturePage (
Optionen,

Funktion (Daten) {
require (‘fs’). writeFileSync (
‘/tmp/screenCapture.testExampleJs.browser..png’,
data.toPng ()
);

process.exit (0);
}}
);
}}
);
}}
);

Wenn Sie Schwierigkeiten haben, treten Sie dem Club bei!

Funktionen innerhalb von Funktionen innerhalb von Funktionen sind schwer zu lesen und sehr schwer zu begründen, weshalb sie als “Rückrufhölle” bezeichnet werden (ich nehme an, die Hölle ist ein verwirrender Ort, um herauszukommen!). Während dies technisch funktioniert, machen Sie Ihren Code zukunftssicher, wenn Sie versuchen, ihn zu verstehen und zu warten.

Es gibt viele Möglichkeiten, die Rückrufhölle zu vermeiden, einschließlich Versprechen und Reaktive Erweiterungen.

Nicht alle CPU-Kerne verwenden

Moderne Prozessoren haben mehrere Kerne – 2, 4, 8, 16, 32. . . Die Zahl steigt weiter.

Dies hatte der Node-Ersteller jedoch nicht im Sinn, als er Node veröffentlichte. Infolgedessen ist Node Single-Threaded, was bedeutet, dass er in einem einzelnen Thread (oder Prozess, wenn Sie es so nennen möchten, obwohl sie nicht identisch sind) ausgeführt wird und nur einen CPU-Kern verwendet.

Das heißt, wenn Sie Node aus Tutorials und Freunden und Code-Snippets gelernt haben und Ihre App auf einem 8-Core-Server bereitgestellt haben, verschwenden Sie 7/8 der verfügbaren Verarbeitungsleistung!

Es ist natürlich eine massive Verschwendung. Wenn Sie diesem Pfad folgen, zahlen Sie am Ende für acht Server, wenn Sie nur einen benötigen. Das heißt, Sie geben 16.000 USD pro Monat aus, wenn 2.000 USD ausreichen (Geldverlust tut immer weh, oder?). All dies, wenn die Lösung ziemlich einfach ist: Verwenden der Cluster Modul.

Ich kann hier nicht auf alle Details eingehen, aber es ist eine einfache Technik, um zu erkennen, wie viele Kerne der aktuelle Computer hat, und dann so viele Knoteninstanzen zu starten. Wenn Fehler erkannt werden, wird die Instanz neu gestartet. So einfach ist die Implementierung (Tutorial) Hier):

var cluster = require (‘cluster’);

if (cluster.isMaster) {
var numWorkers = require (‘os’). cpus (). length;

console.log (‘Master-Cluster einrichten’ + numWorkers + ‘Arbeiter …’);

für (var i = 0; i < numWorkers; i ++) {
cluster.fork ();
}}

cluster.on (‘online’, Funktion (Arbeiter) {
console.log (‘Worker’ + worker.process.pid + ‘ist online’);
});

cluster.on (‘exit’, Funktion (Arbeiter, Code, Signal) {
console.log (‘Worker’ + worker.process.pid + ‘starb mit Code:’ + Code + ‘und Signal:’ + Signal);
console.log (‘Einen neuen Worker starten’);
cluster.fork ();
});
} else {
var app = require (‘express’) ();
app.all (‘/ *’, function (req, res) {res.send (‘process’ + process.pid + ‘sagt hallo!’). end ();})

var server = app.listen (8000, function () {
console.log (‘Process’ + process.pid + ‘hört alle eingehenden Anfragen ab’);
});
}}

Wie Sie sehen können, erledigt cluster.fork () die Magie, und der Rest hört einfach ein paar wichtige Clusterereignisse ab und führt die erforderliche Bereinigung durch.

TypeScript wird nicht verwendet

Okay, es ist kein Fehler, und viele Node-Anwendungen wurden und werden ohne TypeScript geschrieben.

Trotzdem bietet TypeScript die Garantien und die Sicherheit, die Node immer benötigt hat, und in meinen Augen ist es ein Fehler, wenn Sie 2019 für Node entwickeln und TypeScript nicht verwenden (insbesondere, wenn sich das A (Angular) im MEAN-Stack bewegt hat vor langer Zeit zu TypeScript).

Der Übergang ist sanft und TypeScript ähnelt fast genau dem JavaScript, das Sie kennen, mit der Sicherheit von Typen, ES6 und einigen anderen Überprüfungen:

// /lib/controllers/crmController.ts
* als Mungo aus ‘Mungo’ importieren;
{ContactSchema} aus ‘../models/crmModel’ importieren;
{Request, Response} aus ‘express’ importieren;

const Contact = mongoose.model (‘Kontakt’, ContactSchema);
Exportklasse ContactController {

public addNewContact (req: Request, res: Response) {
let newContact = neuer Kontakt (req.body);

newContact.save ((err, contact) => {
if (err) {
res.send (err);
}}
res.json (Kontakt);
});
}}

Ich würde empfehlen, dies nett und freundlich zu überprüfen TypeScript-Tutorial.

Fazit

Der Knoten ist beeindruckend, aber nicht ohne (viele?) Probleme. Dies gilt jedoch für alle neuen und alten Technologien, und wir werden besser daran arbeiten, Node zu verstehen und damit zu arbeiten.

Ich hoffe, diese fünf Tipps verhindern, dass Sie in die Teergrube von mehrjährigen Fehlern und Leistungsproblemen hineingezogen werden. Wenn ich etwas Interessantes verpasst habe, lass es mich bitte wissen und ich werde mehr als glücklich (in der Tat dankbar!) Sein, sie in den Artikel aufzunehmen. ��

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map