NodeJS —— 自定义流的实现

栏目: Node.js · 发布时间: 6年前

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

双工流分别具备 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 的作用是写流。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

人人都是架构师:分布式系统架构落地与瓶颈突破

人人都是架构师:分布式系统架构落地与瓶颈突破

高翔龙 / 电子工业出版社 / 2017-5 / 69

《人人都是架构师:分布式系统架构落地与瓶颈突破》并没有过多渲染系统架构的理论知识,而是切切实实站在开发一线角度,为各位读者诠释了大型网站在架构演变过程中出现一系列技术难题时的解决方案。《人人都是架构师:分布式系统架构落地与瓶颈突破》首先从分布式服务案例开始介绍,重点为大家讲解了大规模服务化场景下企业应该如何实施服务治理;然后在大流量限流/消峰案例中,笔者为大家讲解了应该如何有效地对流量实施管制,避......一起来看看 《人人都是架构师:分布式系统架构落地与瓶颈突破》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器