概述

常见的自定义流有四种,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();
}
}
复制代码

双工流分别具备 ReadableWritable 的功能,但是读和写互不影响,互不关联。

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
复制代码

如果 readabledata 两种读取方式都使用默认先通过 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,会在命令窗口输出 ABC123,其实转换流先作为一个可写流被写入到标准输入中,而此时 stdin 的作用是读流,即读取用户的输入,读取后转换流作为一个可读流调用 pipe,将用户输入的信息通过标准输出写到命令行窗口,此时 stdout 的作用是写流。

总结

自定义流最常见的种类在上面都已经涵盖了,真正的在开发中用到的不多,如果需要写一个自定义流应该比上面的复杂很多,本文主要目的是认识什么是自定义流,并了解写一个自定义流的基本套路。

最后,顺便传播一个好消息:

想上线自己的后台系统或者做自己网站的,机会来了,腾讯云现做活动,新手福利1000减750,云服务器最低2折,云服务器1核2G内存50G硬盘3年最低只要600元!戳此了解详情


作者:PandaShen
链接:https://juejin.im/post/5b5e2061e51d45339e7ed83c
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

NodeJS —— 自定义流的实现的更多相关文章

  1. activiti自定义流程之Spring整合activiti-modeler5.16实例(九):历史任务查询

    注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建        (2)创建流程模型:activiti自定义流程之Spring ...

  2. activiti自定义流程之Spring整合activiti-modeler5.16实例(八):完成个人任务

    注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建        (2)创建流程模型:activiti自定义流程之Spring ...

  3. activiti自定义流程之Spring整合activiti-modeler5.16实例(七):任务列表展示

    注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建        (2)创建流程模型:activiti自定义流程之Spring ...

  4. activiti自定义流程之Spring整合activiti-modeler5.16实例(六):启动流程

    注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建        (2)创建流程模型:activiti自定义流程之Spring ...

  5. activiti自定义流程之Spring整合activiti-modeler5.16实例(五):流程定义列表

    注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建        (2)创建流程模型:activiti自定义流程之Spring ...

  6. activiti自定义流程之Spring整合activiti-modeler5.16实例(四):部署流程定义

    注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建        (2)创建流程模型:activiti自定义流程之Spring ...

  7. activiti自定义流程之Spring整合activiti-modeler5.16实例(三):流程模型列表展示

    注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建        (2)创建流程模型:activiti自定义流程之Spring ...

  8. activiti自定义流程之Spring整合activiti-modeler5.16实例(二):创建流程模型

    注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建 1.maven导包,这里就没有什么多的好说了,直接代码: <depe ...

  9. NodeJS Stream流

    NodeJS Stream流 流数据在网络通信中至关重要,nodeJS用Stream提供了一个抽象接口,node中有很多对象实现了这个接口,提供统一的操作体验 基本流类型 NodeJS中,Stream ...

随机推荐

  1. 用pc构建DIY计算集群

    -----------------------------------------------------------------用pc构建DIY计算集群目录/构建计算集群|-- /0前言|-- /1 ...

  2. jacoco+maven生成单元测试覆盖率报告

    参考:https://www.petrikainulainen.net/programming/maven/creating-code-coverage-reports-for-unit-and-in ...

  3. Oracle 远程访问配置 在 Windows Forms 和 WPF 应用中使用 FontAwesome 图标 C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素” C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper Decimal类型截取保留N位小数向上取, Decimal类型截取保留N位小数并且不进行四舍五入操作

    Oracle 远程访问配置   服务端配置 如果不想自己写,可以通过 Net Manager 来配置. 以下配置文件中的 localhost 改为 ip 地址,否则,远程不能访问. 1.网络监听配置 ...

  4. GSON学习笔记之初识GSON

    引用"JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,採用全然独立于语言的文本格式.为Web应用开发提供了一种理想的数据交换格式. " ...

  5. cocos2dx 纹理优化

    description: 为什么要谈纹理的问题,游戏的画面无时无刻不充斥着图像,通俗意义上一款精致的游戏都有着非常精美的画面.这样往往能给玩家带来更好的游戏体验,这一点也是对于游戏制作者来说所尽力追求 ...

  6. jquery跨域请求json数据

    //服务端生成json数据json.php <?php $json=array("Volvo","BMW","SAAB"); $cb ...

  7. STM32学习之路-感觉自己走到了一个天大的坑里了!

    先前兴致勃勃的来弄16位并口驱动LCD.本以为就须要改下LCD IC的初始化即可了,没想到弄了这么多天最终发现自己走进了一个深坑了 T T 原因是我的开发板是奋斗V5的, 它确实有MCU外扩IO口, ...

  8. Spring Boot Controller

    接上篇文章.HelloWorld程序中我们已经创建了一个HellController,里面包括了响应JSON的方法.本文针对Controller再做一下解说. 回想上篇文章,我们在Controller ...

  9. Codeforces Round #228 (Div. 2) C. Fox and Box Accumulation

    C. Fox and Box Accumulation time limit per test 1 second memory limit per test 256 megabytes input s ...

  10. BZOJ_2120_数颜色_Set+树状数组+主席树

    BZOJ_2120_数颜色_Set+树状数组+主席树 Description 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L ...