Was ist Flow? Wie versteht man den Fluss? Der folgende Artikel wird Ihnen ein tiefgreifendes Verständnis von Streams in Nodejs vermitteln. Ich hoffe, er wird Ihnen hilfreich sein!
Stream ist eine abstrakte Datenschnittstelle, die EventEmitter erbt. Sie kann Daten senden/empfangen, wie unten gezeigt:
Stream ist kein einzigartiges Konzept in Node, sondern ein Betriebssystem . Die grundlegendste Betriebsmethode in Linux |. ist Stream, aber sie ist auf Knotenebene gekapselt und stellt die entsprechende API bereit
Verwenden Sie zunächst den folgenden Code, um eine Datei mit einer Größe von ca. 400 MB zu erstellen [Empfehlung für entsprechende Tutorials: nodejs-Video-Tutorial]
Wenn wir readFile zum Lesen verwenden, ist der folgende Code
normal. Beim Start Der Dienst belegt etwa 10 MB Speicher.
Wenn Sie curl http://127.0.0.1:8000
verwenden, um eine Anfrage zu initiieren, beträgt der Speicher etwa 420 MB, was ungefähr dem gleichen Wert entspricht Größe wie die von uns erstellte Datei. lazy"/>curl http://127.0.0.1:8000
发起请求时,内存变为了 420MB 左右,和我们创建的文件大小差不多
改为使用使用 stream 的写法,代码如下
再次发起请求时,发现内存只占用了 35MB 左右,相比 readFile 大幅减少
如果我们不采用流的模式,等待大文件加载完成在操作,会有如下的问题:
总结来说就是,一次性读取大文件,内存和网络都吃不消
我们读取文件的时候,可以采用读取完成之后在输出数据
上述说到 stream 继承了 EventEmitter 可以是实现监听数据。首先将读取数据改为流式读取,使用 on("data", ()⇒{})
接收数据,最后通过 on("end", ()⇒{})
最后的结果
有数据传递过来的时候就会触发 data 事件,接收这段数据做处理,最后等待所有的数据全部传递完成之后触发 end 事件。
数据是从一个地方流向另一个地方,先看看数据的来源。
http 请求,请求接口来的数据
console 控制台,标准输入 stdin
file 文件,读取文件内容,例如上面的例子
在 source 和 dest 中有一个连接的管道 pipe,基本语法为 source.pipe(dest)
Die CPU-Betriebsgeschwindigkeit ist begrenzt und dient mehreren Programme sind zu groß und brauchen viel Zeit zum Laden.
Zusammenfassung Mit anderen Worten: Das gleichzeitige Lesen einer großen Datei ist zu viel für den Speicher und das NetzwerkWenn wir die Datei lesen, können wir die Daten ausgeben, nachdem der Lesevorgang abgeschlossen ist
🎜🎜Wie oben erwähnt, erbt Stream EventEmitter und kann zur Überwachung von Daten verwendet werden. Ändern Sie zunächst die Lesedaten in Streaming-Lesung, verwenden Sieon("data", ()⇒{})
, um die Daten zu empfangen, und verwenden Sie schließlich on("end", ()⇒ { })
Das Endergebnis🎜🎜🎜🎜Wenn Daten übertragen werden, wird das Datenereignis ausgelöst, die Daten werden zur Verarbeitung empfangen und das Endereignis wird ausgelöst, nachdem alle Daten übertragen wurden. 🎜source.pipe(dest)
, Quelle und Ziel sind über eine Pipe verbunden, sodass Daten von der Quelle zum Ziel fließen können. 🎜🎜Wir müssen das Daten-/Endereignis nicht wie im obigen Code manuell überwachen. Bei der Verwendung von Pipe gelten strenge Anforderungen. Die Quelle muss lesbar sein stream und dest müssen Es ist ein beschreibbarer Stream🎜🎜??? Was genau sind fließende Daten? Was ist ein Chunk im Code? 🎜🎜🎜Wohin – Ziel🎜🎜🎜Drei gängige Ausgabemethoden streamen🎜🎜🎜🎜Konsolenkonsole, Standardausgabe stdout🎜🎜🎜🎜Ein lesbarer Stream ist eine Abstraktion der Quelle, die Daten bereitstellt
Alle Readables implementieren die durch den Stream definierte Schnittstelle.Readable-Klasse? Datei-Stream-Erstellung lesen
fs.createReadStream erstellt ein lesbares ObjektReadable Stream verfügt über zwei Modi,
ture: Zeigt den Fließmodus an
false: Zeigt den Pausenmodus annull: Anfangszustand
Daten werden automatisch aus der untersten Ebene gelesen, bilden ein Flussphänomen und werden der Anwendung über Ereignisse bereitgestellt.
Sie können diesen Modus aufrufen, indem Sie das Datenereignis abhören.
Wenn das Datenereignis hinzugefügt wird und sich Daten im beschreibbaren Stream befinden, werden die Daten an die Ereignisrückruffunktion übertragen. Sie müssen den Datenblock verbrauchen Wenn es nicht verarbeitet wird, gehen die Daten verloren. Rufen Sie die stream.pipe-Methode auf, um Daten an Writeable zu senden. Rufen Sie die stream.resume-Methode auf Die Daten werden im internen Puffer gesammelt und müssen angezeigt werden. Rufen Sie stream.read() auf, um den Datenblock zu lesen- 监听 data 事件 - 调用 stream.resume 方法 - 调用 stream.pipe 方法将数据发送到 Writable
Erstellen Sie einen lesbaren Stream Wann, wir Sie müssen das Readable-Objekt erben und die _read-Methode implementieren
, um einen benutzerdefinierten lesbaren Stream zu erstellen
Wenn die Pufferlänge 0 oder kleiner als der Wert von highWaterMark ist, wird _read aufgerufen, um die Daten von der untersten Ebene abzurufen. Quellcode-Link Daten schreiben Eine Abstraktion des Ziels wird verwendet, um vom Upstream fließende Daten zu verbrauchen und die Daten über einen beschreibbaren Stream auf das Gerät zu schreiben. Ein üblicher Schreibstream ist das Schreiben auf die lokale Festplatte. Merkmale beschreibbarer Streams
Daten durch Schreiben schreiben
ruft ws.write(chunk) auf und gibt false zurück, was angibt, dass die aktuellen Pufferdaten größer oder gleich dem Wert von highWaterMark sind und das Drain-Ereignis ausgelöst wird. Tatsächlich dient es als Warnung. Wir können weiterhin Daten schreiben, aber die unverarbeiteten Daten werden immer im
internen Pufferdes beschreibbaren Streams zurückgehalten. Dies wird nicht erzwungen, bis der Rückstand im Node.js-Puffer voll ist . Unterbrechen: Benutzerdefinierter beschreibbarer Stream Rufen Sie die Methode writable.write auf, um Daten in den Stream zu schreiben. Wenn _write data erfolgreich ist, müssen Sie die nächste Methode aufrufen, um die nächsten Daten zu verarbeiten Rufen Sie writable.end( data) auf, um den beschreibbaren Stream zu beenden, data ist optional. Danach kann das Schreiben nicht mehr aufgerufen werden, um neue Daten hinzuzufügen, andernfalls wird ein Fehler gemeldet
Nachdem die End-Methode aufgerufen wurde und alle zugrunde liegenden Schreibvorgänge abgeschlossen sind, wird das Finish-Ereignis ausgelöstDuplex Stream, sowohl lesbar als auch beschreibbar. Tatsächlich handelt es sich um einen Stream, der Readable und Writable erbt. Er kann sowohl als lesbarer Stream als auch als beschreibbarer Stream verwendet werden. Ein benutzerdefinierter Duplex-Stream muss die Methode _readable und die Methode _write implementieren Das
Transform Stream
Im obigen Beispiel sind die Daten im lesbaren Stream (0/1) und Die beschreibbaren Daten ('F', 'B', 'B') sind isoliert und es besteht keine Beziehung zwischen den beiden. Bei Transform werden die am beschreibbaren Ende geschriebenen Daten jedoch automatisch zum lesbaren Ende hinzugefügt Transformation. Transform erbt von Duplex und hat bereits die Methoden _write und _read implementiert. Sie müssen nur die Methode _transform implementieren.
less → less in CSS konvertiert → CSS-Komprimierung durchführen → CSS komprimieren
Tatsächlich führen less() und minifyCss() beide eine Verarbeitung der Eingabedaten durch und übergeben dann die Ausgabedaten
Im Vergleich zum obigen Beispiel stellen wir fest, dass wir uns für Duplex entscheiden, wenn wir nur einige Konvertierungsarbeiten an den Daten durchführen.
Wenn .pipe() ist Wird von der Quelle aufgerufen und benachrichtigt den Verbraucher darüber, dass Daten übertragen werden müssen. Die Pipeline-Funktion erstellt ein geeignetes Backlog-Paket zum Auslösen von EreignissenWenn der Datencache HighWaterMark überschreitet oder die Schreibwarteschlange beschäftigt ist, gibt .write() false zurück.Wenn false zurückgegeben wird, greift das Backlog-System ein. Es pausiert eingehende Readables von jedem Datenstrom, der Daten sendet. Sobald der Datenstrom geleert ist, wird das Drain-Ereignis ausgelöst und der eingehende Datenstrom wird verbraucht. Sobald die Warteschlange vollständig verarbeitet ist, ermöglicht der Rückstandsmechanismus das erneute Senden der Daten. Der verwendete Speicherplatz wird freigegeben und bereitet sich auf den Empfang des nächsten Datenstapels vor
Teilen Sie die Daten in Blöcke auf und schreiben Sie
Wenn der Block durchläuft Wenn die Warteschlange zu groß oder ausgelastet ist, wird das Lesen angehalten
Wenn die Warteschlange leer ist, lesen Sie die Daten weiter
Weitere Informationen zu Knoten finden Sie unter:nodejs-Tutorial
!Das obige ist der detaillierte Inhalt vonEine eingehende Analyse von Stream in Node. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!