NodeJS实现自定义流的方法


Posted in NodeJs onAugust 01, 2018

前言

NodeJS实现自定义流的方法

常见的自定义流有四种,Readable(可读流)、Writable(可写流)、Duplex(双工流)和 Transform(转换流),常见的自定义流应用有 HTTP 请求、响应, crypto 加密,进程 stdin 通信等等。

stream 模块介绍

在 NodeJS 中要想实现自定义流,需要依赖模块 stream ,直接引入,不需下载,所有种类的流都是继承这个模块内部提供的对应不同种类的类来实现的。

实现一个自定义可读流 Readable

1、创建自定义可读流的类 MyRead

实现自定义可读流需创建一个类为 MyRead ,并继承 stream 中的 Readable 类,重写 _read 方法,这是所有自定义流的固定套路。

let { Readable } = require("stream");

// 创建自定义可读流的类
class MyRead extends Readable {
 constructor() {
 super();
 this.index = 0;
 }

 // 重写自定义的可读流的 _read 方法
 _read() {
 this.index++;
 this.push(this.index + "");

 if (this.index === 3) {
  this.push(null);
 }
 }
}

我们自己写的 _read 方法会先查找并执行,在读取时使用 push 方法将数据读取出来,直到 push 的值为 null 才会停止,否则会认为没有读取完成,会继续调用 _read 。

2、验证自定义可读流

let myRead = new MyRead();

myRead.on("data", data => {
 console.log(data);
});

myRead.on("end", function() {
 console.log("读取完成");
});

// <Buffer 31>
// <Buffer 32>
// <Buffer 33>
// 读取完成

实现一个自定义可写流 Writable

1、创建自定义可写流的类 MyWrite

创建一个类名为 MyWrite ,并继承 stream 中的 Writable 类,重写 _write 方法。

let { Writable } = require("stream");
// 创建自定义可写流的类
class MyWrite extends Writable {
 // 重写自定义的可写流的 _write 方法
 _write(chunk, encoding, callback)) {
 callback(); // 将缓存区写入文件
 }
}

写入内容时默认第一次写入直接写入文件,后面的写入都写入缓存区,如果不调用 callback 只能默认第一次写入文件,调用 callback 会将缓存区清空并写入文件。

2、验证自定义可写流

let myWrite = new MyWrite();
myWrite.write("hello", "utf8", () => {
 console.log("hello ok");
});
myWrite.write("world", "utf8", () => {
 console.log("world ok");
});
// hello ok
// world ok

实现一个自定义双工流 Duplex

1、创建自定义可双工流的类 MyDuplex

双工流的可以理解为即可读又可写的流,创建一个类名为 MyDuplex ,并继承 stream 中的 Duplex 类,由于双工流即可读又可写,需重写 _read 和 _write 方法。

let { Duplex } = require("stream");
// 创建自定义双工流的类
class MyDuplex extends Duplex {
 // 重写自定义的双工流的 _read 方法
 _read() {
 this.push("123");
 this.push(null);
 }
 // 重写自定义的双工流的 _write 方法
 _write(chunk, encoding, callback)) {
 callback();
 }
}

双工流分别具备 Readable 和 Writable 的功能,但是读和写互不影响,互不关联。

2、验证自定义双工流

let myDuplex = new MyDuplex();
myDuplex.on("readable", () => {
 console.log(myDuplex.read(1), "----");
});
setTimeout(() => {
 myDuplex.on("data", data => {
 console.log(data, "xxxx");
 });
}, 3000);
// <Buffer 31> ----
// <Buffer 32> xxxx
// <Buffer 32> ----
// <Buffer 33> xxxx

如果 readable 和 data 两种读取方式都使用默认先通过 data 事件读取,所以一般只选择一个,不要同时使用,可读流的特点是读取数据被消耗掉后就丢失了(缓存区被清空),如果非要两个都用可以加一个定时器(绝对不要这样写)。

实现一个自定义转化流 Transform

1、创建自定义可转化流的类 MyTransform

转化流的意思是即可以当作可读流,又可以当作可写流,创建一个类名为 MyTransform ,并继承 stream 中的 Transform 类,重写 _transform 方法,该方法的参数和 _write 相同。

let { Transform } = require('stream');
// 创建自定义转化流的类
class MyTransform extends Transform {
 // 重写自定义的转化流的 _transform 方法
 _transform(chunk, encoding, callback)) {
  console.log(chunck.toString.toUpperCase());
  callback();
  this.push('123');
 }
}

在自定义转化流的 _transform 方法中,读取数据的 push 方法和 写入数据的 callback 都可以使用。

2、验证自定义转化流

// demo.js
let myTransForm = new MyTransform();
// 使用标准输入
process.stdin.pipe(myTransForm).pipe(process.stdin);

打开命令行窗口执行 node demo.js ,然后输入 abc ,会在命令窗口输出 ABC 和 123 ,其实转换流先作为一个可写流被写入到标准输入中,而此时 stdin 的作用是读流,即读取用户的输入,读取后转换流作为一个可读流调用 pipe ,将用户输入的信息通过标准输出写到命令行窗口,此时 stdout 的作用是写流。

总结

以上所述是小编给大家介绍的NodeJS实现自定义流,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

NodeJs 相关文章推荐
NodeJS学习笔记之网络编程
Aug 03 NodeJs
nodejs教程之环境安装及运行
Nov 21 NodeJs
nodejs中的fiber(纤程)库详解
Mar 24 NodeJs
nodejs调用cmd命令实现复制目录
May 04 NodeJs
nodejs socket实现的服务端和客户端功能示例
Jun 02 NodeJs
ajax +NodeJS 实现图片上传实例
Jun 06 NodeJs
详解nodejs通过响应回写的方式渲染页面资源
Apr 07 NodeJs
Nodejs中的JWT和Session的使用
Aug 21 NodeJs
nodejs中函数的调用实例详解
Oct 31 NodeJs
nodejs对项目下所有空文件夹创建gitkeep的方法
Aug 02 NodeJs
Nodejs 识别图片类型的方法
Aug 15 NodeJs
ubuntu系统下使用pm2设置nodejs开机自启动的方法
May 12 NodeJs
nodejs 生成和导出 word的实例代码
Jul 31 #NodeJs
nodejs(officegen)+vue(axios)在客户端导出word文档的方法
Jul 31 #NodeJs
nodejs 十六进制字符串型数据与btye型数据相互转换
Jul 30 #NodeJs
NodeJS 中Stream 的基本使用
Jul 30 #NodeJs
Nodejs实现爬虫抓取数据实例解析
Jul 05 #NodeJs
nodejs的路径问题的解决
Jun 30 #NodeJs
nodejs用gulp管理前端文件方法
Jun 24 #NodeJs
You might like
PHP中GET变量的使用
2006/10/09 PHP
php 读取文件头判断文件类型的实现代码
2013/08/05 PHP
php微信公众开发之获取周边酒店信息的方法
2014/12/22 PHP
linux中cd命令使用详解
2015/01/08 PHP
php解析xml方法实例详解
2015/05/12 PHP
fsockopen pfsockopen函数被禁用,SMTP发送邮件不正常的解决方法
2015/09/20 PHP
PHP jpgraph库的配置及生成统计图表:折线图、柱状图、饼状图
2017/05/15 PHP
javascript之dhDataGrid Ver2.0.0代码
2007/07/01 Javascript
详谈js遍历集合(Array,Map,Set)
2017/04/06 Javascript
jQuery+Ajax请求本地数据加载商品列表页并跳转详情页的实现方法
2017/07/12 jQuery
vue在使用ECharts时的异步更新和数据加载详解
2017/11/22 Javascript
vue bus全局事件中心简单Demo详解
2018/02/26 Javascript
分析javascript原型及原型链
2018/03/18 Javascript
JavaScript如何实现元素全排列实例代码
2019/05/14 Javascript
jquery中为什么能用$操作
2019/06/18 jQuery
JavaScript实现身份证验证代码实例
2019/08/26 Javascript
vue+elementui实现点击table中的单元格触发事件--弹框
2020/07/18 Javascript
vue中v-model对select的绑定操作
2020/08/31 Javascript
[03:09]显微镜下的DOTA2第一期——带你走进华丽的DOTA2世界
2014/06/20 DOTA
[47:42]完美世界DOTA2联赛PWL S2 GXR vs Ink 第一场 11.19
2020/11/20 DOTA
Python正则表达式的使用范例详解
2014/08/08 Python
Python实现去除图片中指定颜色的像素功能示例
2019/04/13 Python
python实现文件助手中查看微信撤回消息
2019/04/29 Python
妙用itchat! python实现久坐提醒功能
2019/11/25 Python
Python使用plt.boxplot() 参数绘制箱线图
2020/06/04 Python
Python 多线程C段扫描、检测 Ping扫描脚本的实现
2020/09/03 Python
Python绘制K线图之可视化神器pyecharts的使用
2021/03/02 Python
世界第一冲浪品牌:O’Neill
2016/08/30 全球购物
是什么让J2EE适合用来开发多层的分布式的应用
2015/01/16 面试题
防沙治沙典型材料
2014/05/07 职场文书
企业文化理念标语
2014/06/10 职场文书
创建绿色社区汇报材料
2014/08/22 职场文书
退休党员个人对照检查材料思想汇报
2014/09/29 职场文书
教师个人考察材料
2014/12/16 职场文书
导游词之泰山玉皇顶
2019/12/23 职场文书
与Windows10相比Windows11有哪些改进?值不值得升级?
2021/11/21 数码科技