内容简介:常见的自定义流有四种,Readable(可读流)、Writable(可写流)、Duplex(双工流)和 Transform(转换流),常见的自定义流应用有 HTTP 请求、响应,在 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
的作用是写流。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Vue自定义组件(简单实现一个自定义组件)
- golang 实现自定义结构的排序
- Netty实现自定义协议 原 荐
- 安卓自定义注解支持和示例实现
- golang自定义路由控制实现(一)
- Kotlin–›自定义实现支付密码数字键盘
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
精通Git(第2版)
Scott Chacon、Ben Straub / 门佳、刘梓懿 / 人民邮电出版社 / 2017-9 / 89.00元
Git 仅用了几年时间就一跃成为了几乎一统商业及开源领域的版本控制系统。本书全面介绍Git 进行版本管理的基础和进阶知识。全书共10 章,内容由浅入深,展现了普通程序员和项目经理如何有效利用Git提高工作效率,掌握分支概念,灵活地将Git 用于服务器和分布式工作流,如何将开发项目迁移到Git,以及如何高效利用GitHub。一起来看看 《精通Git(第2版)》 这本书的介绍吧!