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);
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. 🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><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><div class="contentsignin">Nach dem Login kopieren</div></div>🎜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);
const http = require('http'); const fs = require('fs'); http.createServer((req, res) => { fs.readFile(moviePath, (err, data) => { res.end(data); }); }).listen(8080);
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'); 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!