当前位置: 首页 > 后端技术 > Node.js

NodeJS——自定义流的实现

时间:2023-04-03 20:23:17 Node.js

阅读原文概述常见的自定义流有四种,Readable(可读流),Writable(可写流),Duplex(双工流)和Transform(转换流),常见的自定义流应用包括HTTP请求、响应、crypto加密、进程stdin通信等。stream模块介绍在NodeJS中实现自定义流需要依赖stream模块,无需下载直接导入。所有类型的流都是通过继承该模块提供的相应类来实现的。实现自定义可读流Readable1,创建自定义可读流类MyRead实现自定义可读流需要创建一个名为MyRead的类,继承stream中的Readable类,重写_read方法。这就是所有自定义Streaming例程。//创建自定义可读流const{Readable}=require("stream");//创建自定义可读流类classMyReadextendsReadable{constructor(){super();这个.index=0;}//覆盖自定义可读流的_read方法_read(){this.index++;this.push(this.index+"");if(this.index===3){this.push(null);}}}自己写的_read方法会先查找执行,读取时使用push方法读取数据,直到push的值为null才会停止,否则会认为读取未完成已完成。会继续调用_read。2.验证自定义可读流//验证自定义可读流letmyRead=newMyRead();myRead.on("data",data=>{console.log(data);});myRead.on("end",function(){console.log("readcomplete");});////////读取完成以实现自定义写入流Writable1。创建一个自定义的可写流类MyWrite创建一个名为MyWrite的类,继承stream中的Writable类,重写_write方法。//创建自定义可写流const{Writable}=require("stream");//创建自定义可写流类classMyWriteextendsWritable{//覆盖自定义可写流的_write方法_write(chunk,encoding,callback)){打回来();//将缓存区写入文件}}写入内容时,默认是第一次写入直接写入文件,后面的所有写入都写入缓存区,如果不调用回调,则默认只能第一次写入文件。调用回调将清除缓冲区并写入文件。2.验证自定义可写流//验证自定义可写流letmyWrite=newMyWrite();myWrite.write("hello","utf8",()=>{console.log("hellook");});myWrite.write("world","utf8",()=>{console.log("worldok");});//hellook//worldok实现自定义双工流Duplex1,创建自定义双工流classMyDuplexDuplexstream可以理解为可读写流,创建一个名为MyDuplex的类,并继承stream中的Duplex类,因为双工流是可读可写的,需要_read和_write方法被改写。//创建自定义双工流const{Duplex}=require("stream");//创建自定义双工流类classMyDuplexextendsDuplex{//覆盖自定义双工流的_read方法_read(){this.push("123");这个。推(空);}//重写自定义双工流的_write方法_write(chunk,encoding,callback)){callback();}}双工流分别具有Readable和Writable的功能,但读写互不影响,互不相关。2.验证自定义双工流//验证自定义双工流letmyDuplex=newMyDuplex();myDuplex.on("readable",()=>{console.log(myDuplex.read(1),"----");});setTimeout(()=>{myDuplex.on("data",data=>{console.log(data,"xxxx");});},3000);//<缓冲区31>----//xxxx//----//xxxx如果默认同时使用可读和数据读取方式,则先读通数据事件,所以一般只选择一、不要同时使用,可读流的特点是读取数据被消费后丢失(清空缓冲区),如果非要两者都用,可以加一个定时器(绝对可以)不要这样写)。实现一个自定义的转换流Transform1,创建一个自定义的可转换流类MyTransform转换流是指可以作为可读流或可写流,创建一个名为MyTransform的类,并继承Transform类中的流,重写_transform方法,该方法的参数与_write相同。//创建自定义转换流const{Transform}=require('stream');//创建自定义转换流类classMyTransformextendsTransform{//覆盖自定义转换流的_transform方法_transform(chunk,encoding,callback)){console.log(chunck.toString.toUpperCase());打回来();this.push('123');}}在自定义转换流的_transform方法中,读取数据可以使用push方法和写入数据的回调。由此可见,Transform类型可以将可读流转换为可写流,也可以将可写流转换为可读流。它的主要目的不是像其他类型的流那样读写数据,而是作为可读流和可写流,实现流的转换,即实现对数据的特殊处理,比如zib模块实现的压缩流,cropo模块实现的加密流。Stream,将存储文件内容的可写流通过pipe方法写入转换流,然后将转换流作为可读流通过pipe方法将处理后的数据响应给浏览器。2.验证自定义转换流程//验证自定义转换流程letmyTransForm=newMyTransform();//使用标准输入process.stdin.pipe(myTransForm).pipe(process.stdin);打开命令行窗口执行nodedemo.js,然后输入abc,命令窗口会输出ABC和123。实际上,转换流首先作为可写流写入标准输入,此时stdin的作用是读取流,即读取用户的输入。读取后转换后的流称为pipe作为可读流,将用户输入的信息通过标准输出写入命令行窗口。这时候stdout的作用就是写流了。综上所述,最常见的自定义流类型上面已经介绍过了,在开发中并没有真正用到。如果需要写自定义流,应该比上面的复杂很多。本文的主要目的是了解什么是自定义流,了解编写自定义流的基本套路。