Node.js-Handbuch, Teil 10: Standardmodule, Streams, Datenbanken, NODE_ENV

Dieses Material schließt die manuelle Übersetzungsserie von Node.js. Heute werden wir über Betriebssysteme, Ereignisse und http-Module sprechen, die Arbeit mit Streams und Datenbanken diskutieren und die Verwendung von Node.js in der Anwendungsentwicklung und -produktion diskutieren.




Node.js OS-Modul


Das Betriebssystemmodul bietet Zugriff auf viele Funktionen, mit denen Sie Informationen zum Betriebssystem und zur Hardware des Computers abrufen können, auf dem Node.js ausgeführt wird. Dies ist ein Standardmodul. Sie müssen es nicht installieren. Um mit dem Code zu arbeiten, schließen Sie es einfach an:

 const os = require('os') 

Hier gibt es einige nützliche Eigenschaften, die insbesondere beim Arbeiten mit Dateien nützlich sein können.

Mit der Eigenschaft os.EOL können os.EOL das im System verwendete Zeilentrennzeichen (ein Zeilenendezeichen) ermitteln. Unter Linux und MacOS ist dies \n , unter Windows \r\n .

Es sollte beachtet werden, dass wir, wenn wir hier „Linux und MacOS“ erwähnen, von POSIX-kompatiblen Plattformen sprechen. Der Kürze halber erwähnen wir hier nicht weniger beliebte Plattformen.

Die Eigenschaft os.constants.signals enthält Informationen zu den Konstanten, die zum Verarbeiten von Prozesssignalen wie SIGHUP , SIGKILL usw. verwendet werden. Hier finden Sie Details dazu.

Die Eigenschaft os.constants.errno enthält die Konstanten, die für Fehlermeldungen verwendet werden - wie EADDRINUSE , EOVERFLOW .

Betrachten Sie nun die Hauptmethoden des os Moduls.

▍os.arch ()


Diese Methode gibt eine Zeichenfolge zurück, die die Architektur des Systems identifiziert, z. B. arm , x64 , arm64 .

▍os.cpus ()


Gibt Informationen zu den im System verfügbaren Prozessoren zurück. Diese Informationen können beispielsweise folgendermaßen aussehen:

 [ { model: 'Intel(R) Core(TM)2 Duo CPU     P8600 @ 2.40GHz',   speed: 2400,   times:    { user: 281685380,      nice: 0,      sys: 187986530,      idle: 685833750,      irq: 0 } }, { model: 'Intel(R) Core(TM)2 Duo CPU     P8600 @ 2.40GHz',   speed: 2400,   times:    { user: 282348700,      nice: 0,      sys: 161800480,      idle: 703509470,      irq: 0 } } ] 

▍os.endianness ()


Gibt BE oder LE je nachdem, welche Bytereihenfolge (Big Engian oder Little Endian) zum Kompilieren der Binärdatei Node.js. verwendet wurde

▍os.freemem ()


Gibt die Menge des freien Systemspeichers in Bytes zurück.

▍os.homedir ()


Gibt den Pfad zum Ausgangsverzeichnis des aktuellen Benutzers zurück. Zum Beispiel '/Users/flavio' .

▍os.hostname ()


Gibt den Hostnamen zurück.

▍os.loadavg ()


Gibt in einem Array die vom Betriebssystem berechneten durchschnittlichen Lastdaten zurück. Diese Informationen sind nur unter Linux und MacOS sinnvoll. Es kann so aussehen:

 [ 3.68798828125, 4.00244140625, 11.1181640625 ] 

▍os.networkInterfaces ()


Gibt Informationen zu den auf dem System verfügbaren Netzwerkschnittstellen zurück. Zum Beispiel:

 { lo0:  [ { address: '127.0.0.1',      netmask: '255.0.0.0',      family: 'IPv4',      mac: 'fe:82:00:00:00:00',      internal: true },    { address: '::1',      netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',      family: 'IPv6',      mac: 'fe:82:00:00:00:00',      scopeid: 0,      internal: true },    { address: 'fe80::1',      netmask: 'ffff:ffff:ffff:ffff::',      family: 'IPv6',      mac: 'fe:82:00:00:00:00',      scopeid: 1,      internal: true } ], en1:  [ { address: 'fe82::9b:8282:d7e6:496e',      netmask: 'ffff:ffff:ffff:ffff::',      family: 'IPv6',      mac: '06:00:00:02:0e:00',      scopeid: 5,      internal: false },    { address: '192.168.1.38',      netmask: '255.255.255.0',      family: 'IPv4',      mac: '06:00:00:02:0e:00',      internal: false } ], utun0:  [ { address: 'fe80::2513:72bc:f405:61d0',      netmask: 'ffff:ffff:ffff:ffff::',      family: 'IPv6',      mac: 'fe:80:00:20:00:00',      scopeid: 8,      internal: false } ] } 

▍os.platform ()


Gibt Informationen zu der Plattform zurück, für die Node.js. kompiliert wurde. Hier sind einige der möglichen Rückgabewerte:

  • Darwin
  • freebsd
  • Linux
  • openbsd
  • win32

▍os.release ()


Gibt eine Zeichenfolge zurück, die die Versionsnummer des Betriebssystems angibt.

▍os.tmpdir ()


Gibt den Pfad zu dem im System angegebenen Verzeichnis zum Speichern temporärer Dateien zurück.

▍os.totalmem ()


Gibt die Gesamtmenge des Systemspeichers in Bytes zurück.

▍os.type ()


Gibt Informationen zurück, die das Betriebssystem identifizieren. Zum Beispiel:

  • Linux - Linux.
  • Darwin - macOS.
  • Windows_NT - Windows.

▍os.uptime ()


Gibt die Systemverfügbarkeit in Sekunden seit dem letzten Neustart zurück.

Node.js Ereignismodul


Das events stellt uns die EventEmitter Klasse zur Verfügung, die für die Arbeit mit Ereignissen auf der Node.js-Plattform ausgelegt ist. Wir haben bereits im siebten Teil dieser Materialreihe ein wenig über dieses Modul gesprochen. Hier ist die Dokumentation dafür. Hier sehen wir uns die API dieses Moduls an. Denken Sie daran, dass Sie zur Verbindung im Code eine Verbindung herstellen müssen, wie dies normalerweise bei Standardmodulen der Fall ist. Danach müssen Sie ein neues EventEmitter Objekt erstellen. Es sieht so aus:

 const EventEmitter = require('events') const door = new EventEmitter() 

Das Objekt der EventEmitter Klasse verwendet Standardmechanismen, insbesondere die folgenden Ereignisse:

  • newListener - Dieses Ereignis wird newListener wenn ein Ereignishandler hinzugefügt wird.
  • removeListener - wird aufgerufen, wenn der Handler entfernt wird.

Betrachten Sie die nützlichsten Methoden von Objekten der EventEmitter Klasse (ein ähnliches Objekt in den Namen der Methoden wird als emitter ).

▍emitter.addListener ()


Ein Alias ​​für die Methode emitter.on() .

▍emitter.emit ()


Erzeugt ein Ereignis. Ruft alle Ereignishandler synchron in der Reihenfolge auf, in der sie registriert wurden.

▍emitter.eventNames ()


Gibt ein Array zurück, das die registrierten Ereignisse enthält.

▍emitter.getMaxListeners ()


Gibt die maximale Anzahl von EventEmitter , die einem Objekt der EventEmitter Klasse hinzugefügt werden können. Der Standardwert ist 10. Bei Bedarf kann dieser Parameter mit der Methode setMaxListeners() erhöht oder verringert werden.

▍emitter.listenerCount ()


Gibt die Anzahl der Ereignishandler zurück, deren Name als Parameter an diese Methode übergeben wird:

 door.listenerCount('open') 

▍emitter.listeners ()


Gibt ein Array von Ereignishandlern für das entsprechende Ereignis zurück, dessen Name an diese Methode übergeben wird:

 door.listeners('open') 

▍emitter.off ()


Ein Alias ​​für die in Knoten 10 eingeführte Methode emitter.removeListener() .

▍emitter.on ()


Registrieren Sie einen Rückruf, der aufgerufen wird, wenn ein Ereignis generiert wird. So verwenden Sie es:

 door.on('open', () => { console.log('Door was opened') }) 

▍emitter.once ()


Es registriert einen Rückruf, der nur einmal aufgerufen wird - beim ersten Auftreten eines Ereignisses, für das dieser Rückruf registriert ist. Zum Beispiel:

 const EventEmitter = require('events') const ee = new EventEmitter() ee.once('my-event', () => { //         }) 

▍emitter.prependListener ()


Wenn Sie einen Handler mit den Methoden on() oder addListener() registrieren, wird dieser Handler am Ende der addListener() hinzugefügt und zuletzt aufgerufen, um das entsprechende Ereignis zu behandeln. Bei Verwendung der prependListener() -Methode wird der Handler an der Vorderseite der Warteschlange hinzugefügt, wodurch er zuerst aufgerufen wird, um das Ereignis zu verarbeiten.

▍emitter.prependOnceListener ()


Diese Methode ähnelt der vorherigen. Wenn ein Handler, der für einen einzelnen Aufruf vorgesehen ist, mit der Methode once() registriert wird, stellt sich heraus, dass er der letzte in der Warteschlange der Handler und der letzte ist, der aufgerufen wird. Mit der Methode prependOnceListener() können Sie einen solchen Handler an der Vorderseite der Warteschlange hinzufügen.

▍emitter.removeAllListeners ()


Diese Methode löscht alle Handler für ein bestimmtes Ereignis, das im entsprechenden Objekt registriert ist. Sie benutzen es so:

 door.removeAllListeners('open') 

▍emitter.removeListener ()


Löscht den angegebenen Handler, der an diese Methode übergeben werden soll. Um den Handler für das spätere Löschen zu speichern, kann der entsprechende Rückruf einer Variablen zugeordnet werden. Es sieht so aus:

 const doSomething = () => {} door.on('open', doSomething) door.removeListener('open', doSomething) 

▍emitter.setMaxListeners ()


Mit dieser Methode können Sie die maximale Anzahl von EventEmitter angeben, die einem einzelnen Ereignis in einer Instanz der EventEmitter Klasse EventEmitter . Wie bereits erwähnt, können Sie standardmäßig bis zu 10 Handler für ein bestimmtes Ereignis hinzufügen. Dieser Wert kann geändert werden. Verwenden Sie diese Methode wie folgt:

 door.setMaxListeners(50) 

Node.js http-Modul


Im achten Teil dieser Materialreihe haben wir bereits über das Standardmodul Node.js http . Er stellt die Entwicklermechanismen zur Verfügung, mit denen HTTP-Server erstellt werden sollen. Es ist das Hauptmodul zur Lösung der Probleme des Datenaustauschs über das Netzwerk in Node.js. Sie können es im Code wie folgt verbinden:

 const http = require('http') 

Es besteht aus Eigenschaften, Methoden und Klassen. Reden wir über sie.

▍Eigenschaften


http.METHODS


Diese Eigenschaft listet alle unterstützten HTTP-Methoden auf:

 > require('http').METHODS [ 'ACL', 'BIND', 'CHECKOUT', 'CONNECT', 'COPY', 'DELETE', 'GET', 'HEAD', 'LINK', 'LOCK', 'M-SEARCH', 'MERGE', 'MKACTIVITY', 'MKCALENDAR', 'MKCOL', 'MOVE', 'NOTIFY', 'OPTIONS', 'PATCH', 'POST', 'PROPFIND', 'PROPPATCH', 'PURGE', 'PUT', 'REBIND', 'REPORT', 'SEARCH', 'SUBSCRIBE', 'TRACE', 'UNBIND', 'UNLINK', 'UNLOCK', 'UNSUBSCRIBE' ] 

http.STATUS_CODES


Es enthält die HTTP-Statuscodes und ihre Beschreibungen:

 > require('http').STATUS_CODES { '100': 'Continue', '101': 'Switching Protocols', '102': 'Processing', '200': 'OK', '201': 'Created', '202': 'Accepted', '203': 'Non-Authoritative Information', '204': 'No Content', '205': 'Reset Content', '206': 'Partial Content', '207': 'Multi-Status', '208': 'Already Reported', '226': 'IM Used', '300': 'Multiple Choices', '301': 'Moved Permanently', '302': 'Found', '303': 'See Other', '304': 'Not Modified', '305': 'Use Proxy', '307': 'Temporary Redirect', '308': 'Permanent Redirect', '400': 'Bad Request', '401': 'Unauthorized', '402': 'Payment Required', '403': 'Forbidden', '404': 'Not Found', '405': 'Method Not Allowed', '406': 'Not Acceptable', '407': 'Proxy Authentication Required', '408': 'Request Timeout', '409': 'Conflict', '410': 'Gone', '411': 'Length Required', '412': 'Precondition Failed', '413': 'Payload Too Large', '414': 'URI Too Long', '415': 'Unsupported Media Type', '416': 'Range Not Satisfiable', '417': 'Expectation Failed', '418': 'I\'ma teapot', '421': 'Misdirected Request', '422': 'Unprocessable Entity', '423': 'Locked', '424': 'Failed Dependency', '425': 'Unordered Collection', '426': 'Upgrade Required', '428': 'Precondition Required', '429': 'Too Many Requests', '431': 'Request Header Fields Too Large', '451': 'Unavailable For Legal Reasons', '500': 'Internal Server Error', '501': 'Not Implemented', '502': 'Bad Gateway', '503': 'Service Unavailable', '504': 'Gateway Timeout', '505': 'HTTP Version Not Supported', '506': 'Variant Also Negotiates', '507': 'Insufficient Storage', '508': 'Loop Detected', '509': 'Bandwidth Limit Exceeded', '510': 'Not Extended', '511': 'Network Authentication Required' } 

http.globalAgent


Diese Eigenschaft verweist auf die globale Instanz der http.Agent Klasse. Es wird zum Verwalten von Verbindungen verwendet. Es kann als Schlüsselkomponente des HTTP-Subsystems Node.js. betrachtet werden. Wir werden weiter unten mehr über die Klasse http.Agent sprechen.

▍Methoden


http.createServer ()


Gibt eine neue Instanz der http.Server Klasse zurück. So verwenden Sie diese Methode zum Erstellen eines HTTP-Servers:

 const server = http.createServer((req, res) => { //      }) 

http.request ()


Ermöglicht das Erstellen einer HTTP-Anforderung an den Server, indem eine Instanz der Klasse http.ClientRequest .

http.get ()


Diese Methode ähnelt http.request() , setzt jedoch die HTTP-Methode automatisch auf GET und ruft automatisch einen Befehl der Form req.end() .

▍ Klassen


Das HTTP-Modul bietet 5 Klassen: Agent , ClientRequest , Server , ServerResponse und IncomingMessage . Betrachten Sie sie.

http.Agent


Die globale Instanz der von Node.js erstellten http.Agent Klasse wird zum Verwalten von Verbindungen verwendet. Es wird als Standardwert für alle HTTP-Anforderungen verwendet und ermöglicht das Einreihen und Wiederverwenden von Sockets. Darüber hinaus unterstützt es einen Socket-Pool, der eine hohe Leistung des Node.js.-Netzwerksubsystems ermöglicht. Bei Bedarf können Sie Ihr eigenes http.Agent Objekt erstellen.

http.ClientRequest


Ein Objekt der http.ClientRequest Klasse, bei der es sich um eine laufende Anforderung handelt, wird beim http.request() Methoden http.request() oder http.get() . Wenn eine Antwort auf eine Anfrage empfangen wird, wird das Antwortereignis http.IncomingMessage , in dem die Antwort übertragen wird - eine Instanz von http.IncomingMessage . Die nach Abschluss der Abfrage erhaltenen Daten können auf zwei Arten verarbeitet werden:

  • Sie können die Methode response.read() aufrufen.
  • Im Handler für response können Sie einen Listener für das Datenereignis konfigurieren, mit dem Sie mit Streaming-Daten arbeiten können.

http.Server


Instanzen dieser Klasse werden zum Erstellen von Servern mit dem Befehl http.createServer() . Nachdem wir ein Serverobjekt haben, können wir seine Methoden verwenden:

  • Die listen() -Methode wird verwendet, um den Server zu starten und das Warten und Verarbeiten eingehender Anforderungen zu organisieren.
  • Die Methode close() stoppt den Server.

http.ServerResponse


Dieses Objekt wird von der http.Server Klasse erstellt und beim http.Server als zweiter Parameter an das request . In der Regel wird solchen Objekten im Code der Name res zugewiesen:

 const server = http.createServer((req, res) => { //res -   http.ServerResponse }) 

In solchen Handlern wird, nachdem die Serverantwort zum Senden an den Client bereit ist, die end() -Methode aufgerufen, die die Antwort vervollständigt. Diese Methode muss nach Abschluss jeder Antwort aufgerufen werden.

Hier sind die Methoden zum Arbeiten mit HTTP-Headern:

  • getHeaderNames() - getHeaderNames() eine Liste der Namen der installierten Header zurück.
  • getHeaders() - gibt eine Kopie der festgelegten HTTP-Header zurück.
  • setHeader('headername', value) - setHeader('headername', value) den Wert für den angegebenen Header fest.
  • getHeader('headername') - gibt den gesetzten Header zurück.
  • removeHeader('headername') - removeHeader('headername') den installierten Header.
  • hasHeader('headername') - gibt true zurück true wenn die Antwort bereits einen Header enthält, dessen Name an diese Methode übergeben wird.
  • headersSent() - gibt true zurück true wenn Header bereits an den Client gesendet wurden.

Nach der Verarbeitung der Header können sie durch Aufrufen der Methode response.writeHead() an den Client gesendet werden, die als ersten Parameter einen Statuscode annimmt. Als zweiter und dritter Parameter kann eine Nachricht, die dem Statuscode und den Headern entspricht, an diesen übergeben werden.

Um Daten an den Client zu senden, wird im Antworttext die Methode write() verwendet. Es sendet gepufferte Daten an den HTTP-Antwortstrom.

Wenn mit dem Befehl response.writeHead() noch keine Header festgelegt wurden, werden zuerst Header mit dem in der Anforderung angegebenen Statuscode und der in der Anforderung angegebenen Nachricht gesendet. Sie können ihre Werte festlegen, indem Sie Werte für die statusMessage statusCode und statusMessage :

 response.statusCode = 500 response.statusMessage = 'Internal Server Error' 

http.IncomingMessage


Ein Objekt der http.IncomingMessage Klasse wird im Verlauf der folgenden Mechanismen erstellt:

  • http.Server - bei der Verarbeitung des request .
  • http.ClientRequest - bei der Behandlung des response .

Es kann verwendet werden, um mit Antwortdaten zu arbeiten. Nämlich:

  • Um den Antwortstatuscode und die entsprechende Nachricht herauszufinden, werden die Eigenschaften statusCode und statusMessage verwendet.
  • Sie können die rawHearders headers rawHearders oder rawHearders (für eine Liste der rohen Header).
  • Sie können die Anforderungsmethode mithilfe der method Eigenschaft ermitteln.
  • Verwenden Sie die Eigenschaft httpVersion , um herauszufinden, welche Version von HTTP verwendet wird.
  • Um die URL url , ist die url Eigenschaft vorgesehen.
  • Mit der socket Eigenschaft können Sie das der Verbindung zugeordnete net.Socket Objekt net.Socket .

Die Antwortdaten werden als Stream dargestellt, da das http.IncomingMessage Objekt die Readable Stream Schnittstelle implementiert.

Arbeiten Sie mit Streams in Node.js.


Threads sind eines der grundlegenden Konzepte, die in Node.js-Anwendungen verwendet werden. Streams sind Tools, mit denen Sie Dateien lesen und schreiben, die Netzwerkinteraktion zwischen Systemen organisieren und Datenaustauschvorgänge im Allgemeinen effektiv implementieren können.

Das Konzept der Threads gilt nicht nur für Node.js. Sie erschienen vor Jahrzehnten in der Unix-Betriebssystemfamilie. Insbesondere können Programme miteinander interagieren und Datenströme über Pipelines übertragen (unter Verwendung des Pipe-Zeichens - | ).

Wenn wir uns beispielsweise vorstellen, eine Datei ohne Verwendung von Streams zu lesen, wird während der Ausführung des entsprechenden Befehls der Inhalt der Datei vollständig in den Speicher eingelesen, wonach mit diesen Inhalten gearbeitet werden kann.

Dank des Flow-Mechanismus können Dateien in Teilen gelesen und verarbeitet werden, sodass keine großen Datenmengen im Speicher gespeichert werden müssen.

Das Stream- Modul Node.js ist die Grundlage, auf der alle APIs basieren, die Streaming unterstützen.

▍Über die Stärken der Verwendung von Streams


Streams haben im Vergleich zu anderen Methoden der Datenverarbeitung folgende Vorteile:

  • Effiziente Speichernutzung. Das Arbeiten mit einem Stream bedeutet nicht, dass große Datenmengen, die dort im Voraus geladen wurden, im Speicher gespeichert werden, bevor sie verarbeitet werden können.
  • Zeitersparnis. Vom Stream empfangene Daten können viel schneller verarbeitet werden, als wenn Sie warten müssen, bis sie vollständig geladen sind, um mit der Verarbeitung zu beginnen.

▍ Beispiel für die Arbeit mit Streams


Ein traditionelles Beispiel für die Arbeit mit Streams zeigt das Lesen einer Datei von der Festplatte.

Betrachten Sie zunächst Code, in dem keine Threads verwendet werden. Mit dem Standardmodul Node.js fs können Sie eine Datei lesen und anschließend als Antwort auf eine von einem HTTP-Server empfangene Anforderung über HTTP übertragen werden:

 const http = require('http') const fs = require('fs') const server = http.createServer(function (req, res) { fs.readFile(__dirname + '/data.txt', (err, data) => {   res.end(data) }) }) server.listen(3000) 

Mit der hier verwendeten Methode readFile() können Sie die gesamte Datei lesen. Wenn der Lesevorgang abgeschlossen ist, wird der entsprechende Rückruf aufgerufen.

Die im Rückruf aufgerufene Methode res.end(data) sendet den Inhalt der Datei an den Client.

Wenn die Dateigröße groß ist, nimmt dieser Vorgang viel Zeit in Anspruch. Hier ist das gleiche Beispiel, das mit Streams neu geschrieben wurde:

 const http = require('http') const fs = require('fs') const server = http.createServer((req, res) => { const stream = fs.createReadStream(__dirname + '/data.txt') stream.pipe(res) }) server.listen(3000) 

Anstatt auf den Moment zu warten, in dem die Datei vollständig gelesen wurde, beginnen wir sofort, ihre Daten an den Client zu übertragen, nachdem der erste Teil dieser Daten zum Senden bereit ist.

▍Pipe () -Methode


Im vorherigen Beispiel haben wir eine Konstruktion des Formulars stream.pipe(res) , in der die Dateistream-Methode pipe() aufgerufen wird. Diese Methode nimmt Daten von ihrer Quelle und sendet sie an das Ziel.

Es wird für einen Stream aufgerufen, der eine Datenquelle darstellt. In diesem Fall ist dies der Dateistream, der an die HTTP-Antwort gesendet wird.

Der Rückgabewert der pipe() -Methode ist der Zielstrom. Dies ist sehr praktisch, da Sie damit mehrere Aufrufe an die pipe() -Methode verketten können:

 src.pipe(dest1).pipe(dest2) 

Dies entspricht einem solchen Design:

 src.pipe(dest1) dest1.pipe(dest2) 

▍API Node.js, die Streams verwenden


Streams sind ein nützlicher Mechanismus. Daher bieten viele Module des Node.js-Kernels Standardfunktionen für die Arbeit mit Streams. Wir listen einige davon auf:

  • process.stdin - gibt einen mit stdin verbundenen Thread zurück.
  • process.stdout - Gibt den mit stdout verbundenen Thread zurück.
  • process.stderr - gibt einen mit stderr verbundenen Thread zurück.
  • fs.createReadStream() - fs.createReadStream() einen lesbaren Stream für die Arbeit mit einer Datei.
  • fs.createWriteStream() - fs.createWriteStream() einen beschreibbaren Stream für die Arbeit mit einer Datei.
  • net.connect() - initiiert eine Stream-basierte Verbindung.
  • http.request() - http.request() eine Instanz der http.ClientRequest Klasse zurück, die den Zugriff auf den zu schreibenden Stream ermöglicht.
  • zlib.createGzip() - komprimiert Daten mithilfe des gzip Algorithmus und sendet sie an den Stream.
  • zlib.createGunzip() - dekomprimiert einen gzip Stream.
  • zlib.createDeflate() - komprimiert Daten mithilfe des deflate Algorithmus und sendet sie an den Stream.
  • zlib.createInflate() - dekomprimiert einen deflate Stream.

▍Verschiedene Arten von Streams


Es gibt vier Arten von Streams:

  • Ein lesbarer Stream ist ein Stream, aus dem Daten gelesen werden können. Sie können keine Daten in einen solchen Stream schreiben. Wenn Daten in einem solchen Stream ankommen, werden sie gepuffert, bis der Datenkonsument beginnt, sie zu lesen.
  • Ein Stream zum Schreiben (beschreibbar) ist ein Stream, in dem Sie Daten senden können. Sie können keine Daten daraus lesen.
  • Duplex-Stream ( Duplex ) - In diesem Stream können Sie Daten senden und daraus lesen. Im Wesentlichen ist dies eine Kombination aus einem Stream zum Lesen und einem Stream zum Schreiben.
  • Stream transformieren ( Transform ) - Solche Streams ähneln Duplex-Streams. Der Unterschied besteht darin, dass die Eingabe dieser Streams das transformiert, was von ihnen gelesen werden kann.

▍Erstellen Sie einen Lesestream


, stream :

 const Stream = require('stream') const readableStream = new Stream.Readable() 

, :

 readableStream.push('hi!') readableStream.push('ho!') 


Writable _write() . :

 const Stream = require('stream') const writableStream = new Stream.Writable() 

_write() :

 writableStream._write = (chunk, encoding, next) => {   console.log(chunk.toString())   next() } 

, :

 process.stdin.pipe(writableStream) 


, , :

 const Stream = require('stream') const readableStream = new Stream.Readable() const writableStream = new Stream.Writable() writableStream._write = (chunk, encoding, next) => {   console.log(chunk.toString())   next() } readableStream.pipe(writableStream) readableStream.push('hi!') readableStream.push('ho!') readableStream.push(null) 

readableStream.push(null) .

, readable :

 readableStream.on('readable', () => { console.log(readableStream.read()) }) 


write() :

 writableStream.write('hey!\n') 

▍ ,


, , end() :

 writableStream.end() 

. , , .

MySQL Node.js


MySQL . Node.js , MySQL-, — , .

mysqljs/mysql . , , 12000 GitHub. , MySQL-.


:

 npm install mysql 


:

 const mysql = require('mysql') 

:

 const options = { user: 'the_mysql_user_name', password: 'the_mysql_user_password', database: 'the_mysql_database_name' } const connection = mysql.createConnection(options) 

:

 connection.connect(err => { if (err) {   console.error('An error occurred while connecting to the DB')   throw err } } 


options :

 const options = { user: 'the_mysql_user_name', password: 'the_mysql_user_password', database: 'the_mysql_database_name' } 

. — :

  • host — , MySQL-, — localhost .
  • port — , — 3306 .
  • socketPath — Unix .
  • debug — , .
  • trace — , .
  • ssl — SSL- .

▍ SELECT


SQL- . query , . — , . . :

 connection.query('SELECT * FROM todos', (error, todos, fields) => { if (error) {   console.error('An error occurred while executing the query')   throw error } console.log(todos) }) 

, :

 const id = 223 connection.query('SELECT * FROM todos WHERE id = ?', [id], (error, todos, fields) => { if (error) {   console.error('An error occurred while executing the query')   throw error } console.log(todos) }) 

, , :

 const id = 223 const author = 'Flavio' connection.query('SELECT * FROM todos WHERE id = ? AND author = ?', [id, author], (error, todos, fields) => { if (error) {   console.error('An error occurred while executing the query')   throw error } console.log(todos) }) 

▍ INSERT


INSERT . , :

 const todo = { thing: 'Buy the milk' author: 'Flavio' } connection.query('INSERT INTO todos SET ?', todo, (error, results, fields) => { if (error) {   console.error('An error occurred while executing the query')   throw error } }) 

, , auto_increment , results.insertId :

 const todo = { thing: 'Buy the milk' author: 'Flavio' } connection.query('INSERT INTO todos SET ?', todo, (error, results, fields) => { if (error) {   console.error('An error occurred while executing the query')   throw error }} const id = results.resultId console.log(id) ) 


end() :

 connection.end() 

.

-


Node.js -.

Node.js . , -, NODE_ENV :

 NODE_ENV=production 

. Linux, , :

 export NODE_ENV=production 

, , .bash_profile ( Bash), .

, :

 NODE_ENV=production node app.js 

Node.js. NODE_ENV production :

  • .
  • .

, Pug — , Express, , NODE_ENV production . Express, , . - . .

Express . , , NODE_ENV :

 app.configure('development', () => { //... }) app.configure('production', () => { //... }) app.configure('production', 'staging', () => { //... }) 

, :

 app.configure('development', () => { app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); }) app.configure('production', () => { app.use(express.errorHandler()) }) 


, , Node.js , . , , , Node.js, - , Node.js.

Liebe Leser! , Node.js, , .

Source: https://habr.com/ru/post/de425667/


All Articles