内容简介:常见的自定义流有四种,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–›自定义实现支付密码数字键盘
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
人人都是架构师:分布式系统架构落地与瓶颈突破
高翔龙 / 电子工业出版社 / 2017-5 / 69
《人人都是架构师:分布式系统架构落地与瓶颈突破》并没有过多渲染系统架构的理论知识,而是切切实实站在开发一线角度,为各位读者诠释了大型网站在架构演变过程中出现一系列技术难题时的解决方案。《人人都是架构师:分布式系统架构落地与瓶颈突破》首先从分布式服务案例开始介绍,重点为大家讲解了大规模服务化场景下企业应该如何实施服务治理;然后在大流量限流/消峰案例中,笔者为大家讲解了应该如何有效地对流量实施管制,避......一起来看看 《人人都是架构师:分布式系统架构落地与瓶颈突破》 这本书的介绍吧!