node.js中通过stream模块实现自定义流

有些时候我们需要自定义一些流,来操作特殊对象,node.js中为我们提供了一些基本流类。

我们新创建的流类需要继承四个基本流类之一(stream.Writeable,stream.Readable,stream.Duplex,stream.Transform),并确保调用了父类构造函数。

 

一、实现自定义的可读流

实现可读流需继承 stream.Readable,并实现 readable._read() 方法。

下面的代码我们实现了一个从数组中读取数据的流

const {Readable} = require('stream');

//这里我们自定义了一个用来读取数组的流
class ArrRead extends Readable {
    constructor(arr,opt) {
        //注意这里,需调用父类的构造函数
        super(opt);
        this.arr = arr;
        this.index = 0;
    }

    //实现 _read() 方法
    _read(size) {
        //如果当前下标等于数组长度,说明数据已经读完
        if (this.index == this.arr.length) {
            this.push(null);
        } else {
            this.arr.slice(this.index,this.index + size).forEach((value) => {
                this.push(value.toString());
            });
            this.index += size;
        }
    }
}

let arr = new ArrRead([1,2,3,4,5,6,7,8,9,0],{
    highWaterMark: 2
});

//这样当我们监听 'data' 事件时,流会调用我们实现的 _read() 方法往缓冲区中读取数据
//然后提供给消费者
arr.on('data',function (data) {
    console.log(data.toString());
});

  

二、实现自定义的可写流

实现可写流必须继承 stream.Writeable ,并实现 writeable._write() 方法。writable._writev() 方法是可选的。

const {Writable} = require('stream');

//这里我们自定义了一个用来写入数组的流
class ArrWrite extends Writable {
    constructor(arr,opt) {
        super(opt);
        this.arr = arr;
    }

    //实现 _write() 方法
    _write(chunk,encoding,callback) {
        this.arr.push(chunk.toString());
        callback();
    }
}

let data = [];
let arr = new ArrWrite(data,{
    highWaterMark: 3
});

arr.write('1');
arr.write('2');
arr.write('3');

console.log(data);

  

三、实现自定义的可读可写流

可读可写流必须继承 stream.Duplex,并实现 readable._read() 和 writable._write() 方法。

const {Duplex} = require('stream');

//这里我们自定义了一个用来写读可写数组的流
class ArrReadWrite extends Duplex {
    constructor(arr,opt) {
        super(opt);
        this.arr = arr;
        this.index = 0;
    }

    //实现 _write() 方法
    _write(chunk,callback) {
        this.arr.push(chunk.toString());
        callback();
    }

    //实现 _read() 方法
    _read(size) {
        //如果当前下标等于数组长度,说明数据已经读完
        if (this.index == this.arr.length) {
            this.push(null);
        } else {
            this.arr.slice(this.index,this.index + size).forEach((value) => {
                this.push(value.toString());
            });
            this.index += size;
        }
    }
}

let data = [];
let arrWR = new ArrReadWrite(data,{
    highWaterMark: 3
});

//往流中写入数据
arrWR.write('1');
arrWR.write('2');
arrWR.write('3');
console.log(data);

//往流中读取数据
console.log(arrWR.read(2).toString());
console.log(arrWR.read(2).toString());

  

四、自定义的转换流

转换流必须继承 stream.Transform,需实现 transform._transform() 方法。

const {Transform} = require('stream');

//这里我们自定义了一个用来转换数组的流
class Trans extends Transform {
    constructor(opt) {
        super(opt);
    }

    _transform(chunk,callback) {
        //将转换后的数据输出到可读流
        this.push(chunk.toString().toUpperCase());
        //参数一是Error对象
        //参数二如果传入,会被转发到 readable.push()
        callback();
    }
}

let t = new Trans({
    highWaterMark: 3
});

t.on('data',function (data) {
    console.log(data.toString());
});

t.write('a');
t.write('b');
t.write('c');

转换流就是将读取到的数据做些计算然后输出。转换流既可以作为可读流,又可以作为可写流。

const {Transform} = require('stream');

//这里我们自定义了一个用来转换数组的流
class Trans extends Transform {
    constructor(opt) {
        super(opt);
    }

    _transform(chunk,function (data) {
    console.log('data',data.toString());
});

//stdin.pipe(t) 表示将我们的标准输入写入到我的转换流 t 中,此时 t 是可写流。
//pipe(process.stdout) 表示将转换流 t 中的数据读取到标准输出中,此时 t 是可读流。
process.stdin.pipe(t).pipe(process.stdout);

  

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇文章主要介绍“基于nodejs的ssh2怎么实现自动化部署”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“基于nodejs...
本文小编为大家详细介绍“nodejs怎么实现目录不存在自动创建”,内容详细,步骤清晰,细节处理妥当,希望这篇“nodejs怎么实现目录不存在自动创建”文章能帮助大...
这篇“如何把nodejs数据传到前端”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这...
本文小编为大家详细介绍“nodejs如何实现定时删除文件”,内容详细,步骤清晰,细节处理妥当,希望这篇“nodejs如何实现定时删除文件”文章能帮助大家解决疑惑...
这篇文章主要讲解了“nodejs安装模块卡住不动怎么解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来...
今天小编给大家分享一下如何检测nodejs有没有安装成功的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文...
本篇内容主要讲解“怎么安装Node.js的旧版本”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎...
这篇“node中的Express框架怎么安装使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家...
这篇文章主要介绍“nodejs如何实现搜索引擎”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“nodejs如何实现搜索引擎...
这篇文章主要介绍“nodejs中间层如何设置”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“nodejs中间层如何设置”文...
这篇文章主要介绍“nodejs多线程怎么实现”,在日常操作中,相信很多人在nodejs多线程怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法...
这篇文章主要讲解了“nodejs怎么分布式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“nodejs怎么分布式”...
本篇内容介绍了“nodejs字符串怎么转换为数组”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情...
这篇文章主要介绍了nodejs如何运行在php服务器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇nodejs如何运行在php服务器文章都...
本篇内容主要讲解“nodejs单线程如何处理事件”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“nodejs单线程如何...
这篇文章主要介绍“nodejs怎么安装ws模块”,在日常操作中,相信很多人在nodejs怎么安装ws模块问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法...
本篇内容介绍了“怎么打包nodejs代码”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!
本文小编为大家详细介绍“nodejs接收到的汉字乱码怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“nodejs接收到的汉字乱码怎么解决”文章能帮助大家解...
这篇“nodejs怎么同步删除文件”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇...
今天小编给大家分享一下nodejs怎么设置淘宝镜像的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希