Heim >Web-Frontend >js-Tutorial >Streams in Node.js verstehen
Verwandte Empfehlungen: „nodejs-Tutorial“
Für die meisten Studenten mit Back-End-Erfahrung ist das Stream-Objekt ein vernünftiges und häufiges Objekt, aber für Front-End-Studenten ist Stream nicht so selbstverständlich ist auf Github? Es gibt einen Artikel mit mehr als 9.000 Sternen, der vorstellt, was Stream ist – Stream-Handbuch (https://link.zhihu.com/?target=https%3A//github.com/substack/stream-handbook ). Um Stream besser zu verstehen, fassen wir es anhand dieses Artikels kurz zusammen.
ls | grep *.js
Beim Schreiben von Skripten stoßen wir häufig auf Codes wie diesen. Verwenden Sie
|
, um zwei Befehle zu verbinden und das Ergebnis des vorherigen Befehls als Parameter des nächsten Befehls zu übergeben, sodass Daten wie Wasser sind durch eine Pipe fließen, und jeder Befehl ist wie ein Prozessor, der eine Verarbeitung der Daten durchführt, daher wird | als „Pipeline-Symbol bezeichnet. |
连接两条命令,把前一个命令的结果作为后一个命令的参数传入,这样数据像是水流在管道中传递,每个命令类似一个处理器,对数据做一些加工,因此 | 被称为 “管道符号”。
从程序角度而言流是有方向的数据,按照流动方向可以分为三种流
设备流向程序:readable
程序流向设备:writable
双向:duplex、transform
NodeJS 关于流的操作被封装到了 Stream 模块,这个模块也被多个核心模块所引用。按照 Unix 的哲学:一切皆文件,在 NodeJS 中对文件的处理多数使用流来完成
普通文件
设备文件(stdin、stdout)
网络文件(http、net)
有一个很容易忽略的知识点:在 NodeJS 中所有的 Stream 都是 EventEmitter 的实例。
我们写程序忽然需要读取某个配置文件 config.json,这时候简单分析一下
我们应该使用 readable 流来做此事
const fs = require('fs'); const FILEPATH = '...'; const rs = fs.createReadStream(FILEPATH);
通过 fs 模块提供的 createReadStream()
方法我们轻松的创建了一个可读的流,这时候 config.json 的内容从设备流向程序。我们并没有直接使用 Stream 模块,因为 fs 内部已经引用了 Stream 模块,并做了封装。
有了数据后我们需要处理,比如需要写到某个路径 DEST ,这时候我们遍需要一个 writable 的流,让数据从程序流向设备。
const ws = fs.createWriteStream(DEST);
两种流都有了,也就是两个数据加工器,那么我们如何通过类似 Unix 的管道符号 |
来链接流呢?在 NodeJS 中管道符号就是 pipe()
Aus Programmsicht handelt es sich bei Stream um
Richtungsdaten, die in drei Arten unterteilt werden können FlüsseGerätefluss zum Programm: lesbar
Programmfluss zum Gerät: beschreibbar
bidirektional: Duplex, Transformation
const fs = require('fs'); const FILEPATH = '...'; const rs = fs.createReadStream(FILEPATH); const ws = fs.createWriteStream(DEST); rs.pipe(ws);🎜Wir können es einfach über
createReadStream()-Methode, die vom fs-Modul bereitgestellt wird. Ein lesbarer Stream, wenn der Inhalt von 🎜config.json vom Gerät zum Programm fließt. Wir haben das Stream-Modul nicht direkt verwendet, da fs das Stream-Modul bereits intern referenziert und gekapselt hat. 🎜🎜Nachdem wir die Daten haben, müssen wir sie verarbeiten. Zu diesem Zeitpunkt benötigen wir einen beschreibbaren Stream, damit die Daten vom Programm zum Gerät fließen können. 🎜<pre class="brush:php;toolbar:false">const fs = require('fs');
const rs = fs.createReadStream('./package.json');
const ws = fs.createWriteStream('./package-lower.json');
rs.pipe(lower).pipe(ws);</pre>🎜Es gibt zwei Streams, also zwei Datenprozessoren. Wie verknüpfen wir die Streams also über das Unix-ähnliche Pipe-Symbol <code>|
? Das Pipe-Symbol in NodeJS ist die Methode pipe()
. 🎜rs.pipe(lower).pipe(acsii).pipe(ws);🎜Auf diese Weise verwenden wir den Stream, um eine einfache Dateikopierfunktion zu implementieren. Das Implementierungsprinzip der Methode „pipe()“ wird später erwähnt, aber es gibt eine Sache, die es zu beachten gilt: Die Daten müssen vom Upstream nach weitergeleitet werden der Downstream, also von einer lesbaren Stream-Pipe zu einem beschreibbaren Stream. 🎜🎜Verarbeiten Sie die Daten🎜🎜Die oben genannten lesbaren und beschreibbaren Streams nennen wir Prozessoren, was eigentlich nicht angemessen ist, da wir nichts verarbeiten, sondern nur die Daten lesen und dann speichern. 🎜🎜Ändern Sie bei Bedarf alle Buchstaben in der lokalen Datei 🎜package.json🎜 in Kleinbuchstaben und speichern Sie sie in der Datei package-lower.json im selben Verzeichnis. 🎜🎜Zu diesem Zeitpunkt müssen wir einen Zwei-Wege-Stream verwenden, der auf die Konvertierung von Zeichen in Kleinbuchstaben spezialisiert ist. 🎜
const http = require('http'); const fs = require('fs'); http.createServer((req, res) => { fs.readFile(moviePath, (err, data) => { res.end(data); }); }).listen(8080);🎜Zu diesem Zeitpunkt können wir sehen, warum das so ist aufgerufene Pipe()-Verbindung Der Stream ist ein Prozessor, der von einem lesbaren Stream zu einem beschreibbaren Stream weitergeleitet werden muss: 🎜🎜🎜lower: niedriger ist stromabwärts, also muss niedriger ein sein beschreibbarer Stream 🎜🎜lower -> Wir werden die spezifische Verwendung von Duplex oder Transformation später erwähnen. 🎜🎜Natürlich, wenn wir einige zusätzliche Verarbeitungsaktionen haben, wie zum Beispiel Buchstaben, die in ASCII-Codes umgewandelt werden müssen, vorausgesetzt, es gibt einen ASCII-Stream, dann kann unser Code sein 🎜
const http = require('http'); const fs = require('fs'); http.createServer((req, res) => { fs.createReadStream(moviePath).pipe(res); }).listen(8080);🎜Ähnlich muss auch ASCII ein bidirektionaler Stream sein. Die Logik dieser Verarbeitung ist sehr klar. Welche Vorteile hat die Verwendung von Streams neben klarem Code? 🎜🎜Warum Sie Stream verwenden sollten🎜🎜Es gibt ein Szenario, in dem ein Benutzer ein Video online ansehen muss. Angenommen, wir geben den Filminhalt über eine HTTP-Anfrage an den Benutzer zurück, dann könnte der Code so geschrieben sein🎜
const http = require('http'); const fs = require('fs'); http.createServer((req, res) => { fs.readFile(moviePath, (err, data) => { res.end(data); }); }).listen(8080);
这样的代码又两个明显的问题
电影文件需要读完之后才能返回给客户,等待时间超长
电影文件需要一次放入内存中,相似动作多了,内存吃不消
用流可以讲电影文件一点点的放入内存中,然后一点点的返回给客户(利用了 HTTP 协议的 Transfer-Encoding: chunked 分段传输特性),用户体验得到优化,同时对内存的开销明显下降
const http = require('http'); const fs = require('fs'); http.createServer((req, res) => { fs.createReadStream(moviePath).pipe(res); }).listen(8080);
除了上述好处,代码优雅了很多,拓展也比较简单。比如需要对视频内容压缩,我们可以引入一个专门做此事的流,这个流不用关心其它部分做了什么,只要是接入管道中就可以了
const http = require('http'); const fs = require('fs'); const oppressor = require(oppressor); http.createServer((req, res) => { fs.createReadStream(moviePath) .pipe(oppressor) .pipe(res); }).listen(8080);
可以看出来,使用流后,我们的代码逻辑变得相对独立,可维护性也会有一定的改善,关于几种流的具体使用方式且听下回分解。
更多编程相关知识,请访问:编程视频课程!!
Das obige ist der detaillierte Inhalt vonStreams in Node.js verstehen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!