Maison > Article > interface Web > Comprendre les flux dans Node.js
Recommandations associées : "Tutoriel nodejs"
Pour la plupart des étudiants ayant une expérience back-end, l'objet Stream est un objet raisonnable et courant , mais Stream, camarade de classe front-end, n'est pas si pris pour acquis. Il existe même un article avec plus de 9 000 étoiles sur github présentant ce qu'est Stream - stream-handbook (https://link.zhihu.com/?target=https% 3A //github.com/substack/stream-handbook). Afin de mieux comprendre Stream, résumons-le brièvement sur la base de cet article.
Le flux est un concept très courant et important dans les systèmes Unix. Dans la terminologie, le flux est une abstraction des périphériques d'entrée et de sortie.
ls | grep *.js
Nous rencontrons souvent du code comme celui-ci lors de l'écriture de scripts. Utilisez |
pour connecter deux commandes et transmettre le résultat de la commande précédente comme paramètre de cette dernière. , les données sont transmises comme l'eau dans un tuyau, et chaque commande est comme un processeur qui effectue un certain traitement sur les données, donc | est appelé "symbole du tuyau ".
Du point de vue du programme, un flux est des données dirigées, qui peuvent être divisées en trois types selon la direction du flux
Flux de l'appareil vers le programme : lisible
Flux du programme vers l'appareil : inscriptible
Bidirectionnel : duplex , transform
Les opérations de flux de NodeJS sont encapsulées dans le module Stream, qui est également référencé par plusieurs modules principaux. Selon la philosophie Unix : tout est un fichier, la plupart des traitements de fichiers dans NodeJS utilisent des flux pour compléter les
fichiers ordinaires
fichiers de périphérique ( stdin , stdout)
Fichiers réseau (http, net)
Il y a un point de connaissance qui est facilement négligé : tous les flux dans NodeJS sont tous instances de EventEmitter.
Lorsque nous écrivons un programme, nous avons soudainement besoin de lire un certain fichier de configuration config.json À ce stade, nous analyserons brièvement le
const fs = require('fs'); const FILEPATH = '...'; const rs = fs.createReadStream(FILEPATH);Nous créons facilement un flux lisible grâce à la méthode
fournie par le module fs À ce stade, le contenu de createReadStream()
config.json circule de l'appareil vers le programme. Nous n'avons pas utilisé le module Stream directement car fs a déjà référencé le module Stream en interne et l'a encapsulé.
const ws = fs.createWriteStream(DEST);Maintenant que nous avons deux flux, c'est-à-dire deux processeurs de données, comment pouvons-nous connecter les flux via le symbole pipe de type Unix
? Dans NodeJS, le symbole du tuyau est la méthode |
. pipe()
const fs = require('fs'); const FILEPATH = '...'; const rs = fs.createReadStream(FILEPATH); const ws = fs.createWriteStream(DEST); rs.pipe(ws);De cette façon, nous utilisons des flux pour implémenter une simple fonction de copie de fichier. Le principe d'implémentation de la méthode pipe() sera mentionné plus tard, mais il y a une chose à noter : les données doivent être redirigées depuis de l'amont vers l'aval, c'est-à-dire Pipe d'un flux lisible vers un flux inscriptible. Traiter les donnéesLes flux lisibles et inscriptibles sont mentionnés ci-dessus. Nous les appelons processeurs. En fait, ce n'est pas approprié car nous ne traitons rien, nous lisons simplement les données, puis. Stocker des données. Si nécessaire, modifiez toutes les lettres du fichier
package.json local en minuscules et enregistrez-le dans le fichier package-lower.json dans le même répertoire.
À l'heure actuelle, nous devons utiliser un flux bidirectionnel. Supposons que nous ayons un flux inférieur qui gère spécifiquement la conversion des caractères en minuscules. Ensuite, le code écrit ressemble probablement à ceciconst fs = require('fs'); const rs = fs.createReadStream('./package.json'); const ws = fs.createWriteStream('./package-lower.json'); rs.pipe(lower).pipe(ws);At. cette fois, nous pouvons voir pourquoi le flux connecté par pipe() est appelé un processeur. D'après ce qui est dit ci-dessus, le tuyau doit être redirigé d'un flux lisible vers un flux inscriptible :
rs.pipe(lower).pipe(acsii).pipe(ws);De même, ascii doit également être un flux bidirectionnel. La logique de ce traitement est très claire, donc en plus d'un code clair, quels sont les avantages de l'utilisation des flux ? Pourquoi Stream doit être utiliséIl existe un scénario dans lequel un utilisateur doit regarder une vidéo en ligne. Supposons que nous renvoyions le contenu d'un film à l'utilisateur via une requête HTTP, le code peut alors être écrit. comme ça
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);
可以看出来,使用流后,我们的代码逻辑变得相对独立,可维护性也会有一定的改善,关于几种流的具体使用方式且听下回分解。
更多编程相关知识,请访问:编程视频课程!!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!