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服务器(9):实现非阻塞操作
Dec 18 NodeJs
NodeJS制作爬虫全过程
Dec 22 NodeJs
nodejs实现遍历文件夹并统计文件大小
May 28 NodeJs
浅析nodejs实现Websocket的数据接收与发送
Nov 19 NodeJs
让nodeJS支持ES6的词法----babel的安装和使用方法
Jul 31 NodeJs
nodejs创建简易web服务器与文件读写的实例
Sep 07 NodeJs
nodejs aes 加解密实例
Oct 10 NodeJs
nodejs使用async模块同步执行的方法
Mar 02 NodeJs
nodejs使用node-xlsx生成excel的方法示例
Aug 22 NodeJs
nodejs nedb 封装库与使用方法示例
Feb 06 NodeJs
Nodejs实现WebSocket代码实例
May 19 NodeJs
一文秒懂nodejs中的异步编程
Jan 28 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使用正则表达式获取微博中的话题和对象名
2015/07/18 PHP
ZF框架实现发送邮件的方法
2015/12/03 PHP
php的socket编程详解
2016/11/20 PHP
PHP字符串与数组处理函数用法小结
2020/01/07 PHP
IE和Firefox下javascript的兼容写法小结
2008/12/10 Javascript
收集的10个免费的jQuery相册
2011/02/26 Javascript
Javascript中的delete介绍
2012/09/02 Javascript
JS保存、读取、换行、转Json报错处理方法
2013/06/14 Javascript
基于jQuery实现点击列表加载更多效果
2016/05/31 Javascript
浅谈Jquery中Ajax异步请求中的async参数的作用
2016/06/06 Javascript
功能强大的Bootstrap使用手册(一)
2016/08/02 Javascript
react-native之ART绘图方法详解
2017/08/08 Javascript
使用jQuery实现页面定时弹出广告效果
2017/08/24 jQuery
浅谈webpack编译vue项目生成的代码探索
2017/12/11 Javascript
微信小程序上传图片实例
2018/05/28 Javascript
Object.keys() 和 Object.getOwnPropertyNames() 的区别详解
2020/05/21 Javascript
从源码角度来回答keep-alive组件的缓存原理
2021/01/18 Javascript
Python3访问并下载网页内容的方法
2015/07/28 Python
Python简单实现TCP包发送十六进制数据的方法
2016/04/16 Python
Python中BeautifuSoup库的用法使用详解
2019/11/15 Python
Python list运算操作代码实例解析
2020/01/20 Python
python3+opencv 使用灰度直方图来判断图片的亮暗操作
2020/06/02 Python
使用keras时input_shape的维度表示问题说明
2020/06/29 Python
python 模拟登陆github的示例
2020/12/04 Python
python爬虫利用代理池更换IP的方法步骤
2021/02/21 Python
HTML5之SVG 2D入门6—视窗坐标系与用户坐标系及变换概述
2013/01/30 HTML / CSS
你的自行车健身专家:FaFit24
2016/11/16 全球购物
什么时候需要进行强制类型转换
2016/09/03 面试题
党校培训思想汇报
2014/01/03 职场文书
娱乐节目策划方案
2014/06/10 职场文书
我为党旗添光彩演讲稿
2014/09/10 职场文书
运动会广播稿诗歌版
2014/09/12 职场文书
快递员岗位职责
2014/09/12 职场文书
奖励申请报告范文
2015/05/15 职场文书
公司借条范本
2015/05/25 职场文书
JavaScript 实现页面滚动动画
2021/04/24 Javascript