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 npm常用命令
Jun 14 NodeJs
Nodejs 发送Post请求功能(发短信验证码例子)
Feb 09 NodeJs
Nodejs多站点切换Htpps协议详解及简单实例
Feb 23 NodeJs
NodeJs安装npm包一直失败的解决方法
Apr 28 NodeJs
Nodejs中使用captchapng模块生成图片验证码
May 18 NodeJs
详解使用PM2管理nodejs进程
Oct 24 NodeJs
nodejs acl的用户权限管理详解
Mar 14 NodeJs
详解nodejs通过响应回写的方式渲染页面资源
Apr 07 NodeJs
详解NodeJS Https HSM双向认证实现
Mar 12 NodeJs
nodejs实现百度舆情接口应用示例
Feb 07 NodeJs
nodejs中内置模块fs,path常见的用法说明
Nov 07 NodeJs
在nodejs中创建child process的方法
Jan 26 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快速统计某个数据库中每张表的数据量
2012/09/04 PHP
关于PHP实现异步操作的研究
2013/02/03 PHP
PHP生成Gif图片验证码
2013/10/27 PHP
完美实现wordpress禁止文章修订和自动保存的方法
2014/11/03 PHP
PHP程序员的技术成长规划
2016/03/25 PHP
php微信开发之自定义菜单完整流程
2016/10/08 PHP
某页码显示的helper 少量调整,另附js版
2010/09/12 Javascript
超级有用的13个基于jQuery的内容滚动插件和教程
2011/07/31 Javascript
JavaScript字符串对象split方法入门实例(用于把字符串分割成数组)
2014/10/16 Javascript
javascript去除空格方法小结
2015/05/21 Javascript
详解Node.js模板引擎Jade入门
2018/01/19 Javascript
vue使用codemirror的两种用法
2019/08/27 Javascript
[04:53]DOTA2英雄基础教程 祈求者
2014/01/03 DOTA
[03:55]2014DOTA2国际邀请赛 Fnatic经理采访赢DK在情理之中
2014/07/10 DOTA
[03:05]《我与DAC》之xiao8:DAC与BG
2018/03/27 DOTA
Python cookbook(数据结构与算法)找出序列中出现次数最多的元素算法示例
2018/03/15 Python
python 实现一次性在文件中写入多行的方法
2019/01/28 Python
解决Django连接db遇到的问题
2019/08/29 Python
Python 闭包,函数分隔作用域,nonlocal声明非局部变量操作示例
2019/10/14 Python
Python 解决OPEN读文件报错 ,路径以及r的问题
2019/12/19 Python
python为QT程序添加图标的方法详解
2020/03/09 Python
CSS3制作漂亮的照片墙的实现代码
2016/06/08 HTML / CSS
CSS3制作酷炫的三维相册效果
2016/07/01 HTML / CSS
澳大利亚顶级美发和美容贸易超市:glamaCo
2020/01/19 全球购物
普通简短的个人自我评价
2014/02/15 职场文书
《我要的是葫芦》教学反思
2014/02/23 职场文书
浪费资源的建议书
2014/03/12 职场文书
优秀教师演讲稿
2014/05/06 职场文书
小学课外活动总结
2014/07/09 职场文书
银行贷款收入证明
2014/10/17 职场文书
回复函格式及范文
2015/07/14 职场文书
社区服务活动感想
2015/08/11 职场文书
python numpy中setdiff1d的用法说明
2021/04/22 Python
JavaScript控制台的更多功能
2021/04/28 Javascript
Python 如何将integer转化为罗马数(3999以内)
2021/06/05 Python
使用HBuilder制作一个简单的HTML5网页
2022/07/07 HTML / CSS