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服务器(2):nodejs服务器的构成分析
Dec 18 NodeJs
nodejs 中模拟实现 emmiter 自定义事件
Feb 22 NodeJs
详解NodeJs支付宝移动支付签名及验签
Jan 06 NodeJs
Nodejs中使用captchapng模块生成图片验证码
May 18 NodeJs
详解Windows下安装Nodejs步骤
May 18 NodeJs
NodeJS实现微信公众号关注后自动回复功能
May 31 NodeJs
基于nodejs+express4.X实现文件下载的实例代码
Jul 13 NodeJs
NodeJS实现视频转码的示例代码
Nov 18 NodeJs
使用nodejs+express实现简单的文件上传功能
Dec 27 NodeJs
Nodejs中crypto模块的安全知识讲解
Jan 03 NodeJs
NodeJS实现自定义流的方法
Aug 01 NodeJs
用Electron写个带界面的nodejs爬虫的实现方法
Jan 29 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设计模式之单例模式代码
2016/06/11 PHP
功能强大的php分页函数
2016/07/20 PHP
JS 建立对象的方法
2007/04/21 Javascript
JavaScript 入门·JavaScript 具有全范围的运算符
2007/10/01 Javascript
javascript function调用时的参数检测常用办法
2010/02/26 Javascript
JQuery优缺点分析说明
2011/04/10 Javascript
jQuery 数据缓存模块进化史详细介绍
2012/11/19 Javascript
JavaScript使用DeviceOne开发实战(三)仿微信应用
2015/12/02 Javascript
JS实现把鼠标放到链接上出现滚动文字的方法
2016/04/06 Javascript
微信小程序 循环及嵌套循环的使用总结
2017/09/26 Javascript
微信小程序实现日期格式化和倒计时
2020/11/01 Javascript
深入了解query和params的使用区别
2019/06/24 Javascript
js实现窗口全屏示例详解
2019/09/17 Javascript
[04:49]2014DOTA2国际邀请赛 Newbee顺利挺进总决赛 ImbaTV独家专访
2014/07/19 DOTA
python通过pil将图片转换成黑白效果的方法
2015/03/16 Python
python操作ssh实现服务器日志下载的方法
2015/06/03 Python
详解python3百度指数抓取实例
2016/12/12 Python
详解将Django部署到Centos7全攻略
2018/09/26 Python
对Python中plt的画图函数详解
2018/11/07 Python
python顺序执行多个py文件的方法
2019/06/29 Python
Python3 翻转二叉树的实现
2019/09/30 Python
python自动化实现登录获取图片验证码功能
2019/11/20 Python
总结30个CSS3选择器
2017/04/13 HTML / CSS
浅谈three.js中的needsUpdate的应用
2012/11/12 HTML / CSS
HTML5轻松实现全屏视频背景的示例
2018/04/23 HTML / CSS
Mixbook加拿大:照片书,照片卡,剪贴簿,年历和日历
2017/02/21 全球购物
台湾菁英交友:结识黄金单身的台湾人
2018/01/22 全球购物
沙特阿拉伯网上购物:Sayidaty Mall
2018/05/06 全球购物
Urban Outfitters德国官网:美国跨国生活方式零售公司
2018/05/21 全球购物
中央空调节能方案
2014/06/15 职场文书
人事行政经理岗位职责
2014/06/18 职场文书
小学生交通安全寄语
2015/02/27 职场文书
单方投资意向书
2015/05/11 职场文书
Python实现DBSCAN聚类算法并样例测试
2021/06/22 Python
python分分钟绘制精美地图海报
2022/02/15 Python
sql注入报错之注入原理实例解析
2022/06/10 MySQL