node.js使用stream模块实现自定义流示例


Posted in Javascript onFebruary 13, 2020

本文实例讲述了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, encoding, 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, encoding, 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, encoding, callback) {
    //将转换后的数据输出到可读流
    this.push(chunk.toString().toUpperCase());
    //参数一是Error对象
    //参数二如果传入,会被转发到 readable.push()
    callback();
  }
}
let t = new Trans({
  highWaterMark: 3
});
t.on('data', function (data) {
  console.log('data', data.toString());
});
//stdin.pipe(t) 表示将我们的标准输入写入到我的转换流 t 中,此时 t 是可写流。
//pipe(process.stdout) 表示将转换流 t 中的数据读取到标准输出中,此时 t 是可读流。
process.stdin.pipe(t).pipe(process.stdout);

希望本文所述对大家node.js程序设计有所帮助。

Javascript 相关文章推荐
javascript客户端遍历控件与获取父容器对象示例代码
Jan 06 Javascript
全面解析bootstrap格子布局
May 22 Javascript
Vue.js一个文件对应一个组件实践
Oct 27 Javascript
js实现的在线调色板功能完整实例
Dec 21 Javascript
vue.js 获取select中的value实例
Mar 01 Javascript
JavaScript实现简单的隐藏式侧边栏功能示例
Aug 31 Javascript
Element Input组件分析小结
Oct 11 Javascript
使用element-ui table expand展开行实现手风琴效果
Mar 15 Javascript
vue中的过滤器及其时间格式化问题
Apr 09 Javascript
vue 导出文件,携带请求头token操作
Sep 10 Javascript
javascript实现前端分页功能
Nov 26 Javascript
vue组件vue-esign实现电子签名
Apr 21 Vue.js
Vue export import 导入导出的多种方式与区别介绍
Feb 12 #Javascript
JS FormData对象使用方法实例详解
Feb 12 #Javascript
JS+HTML实现自定义上传图片按钮并显示图片功能的方法分析
Feb 12 #Javascript
微信小程序实现树莓派(raspberry pi)小车控制
Feb 12 #Javascript
JavaScript 替换所有匹配内容及正则替换方法
Feb 12 #Javascript
使用webpack搭建pixi.js开发环境
Feb 12 #Javascript
十分钟教你上手ES2020新特性
Feb 12 #Javascript
You might like
php银联网页支付实现方法
2015/03/04 PHP
PHP实现加密文本文件并限制特定页面的存取的效果
2016/10/21 PHP
Yii框架 session 数据库存储操作方法示例
2019/11/18 PHP
jQuery validate 中文API 附validate.js中文api手册
2010/07/31 Javascript
jQuery获取css z-index在各种浏览器中的返回值
2010/09/15 Javascript
需要做特殊处理的DOM元素属性的访问
2010/11/05 Javascript
关于js new Date() 出现NaN 的分析
2012/10/23 Javascript
javascript定义变量时带var与不带var的区别分析
2015/01/12 Javascript
使用jQuery获得内容以及内容的属性
2015/02/26 Javascript
jQuery获得包含margin的outerWidth和outerHeight的方法
2015/03/25 Javascript
JavaScript获取网页表单action属性的方法
2015/04/02 Javascript
js 判断各种数据类型的简单方法(推荐)
2016/08/29 Javascript
JavaScript基本类型值-Number类型
2017/02/24 Javascript
关于Bootstrap按钮组件消除黄框的方法
2017/05/19 Javascript
深入理解vue.js中的v-if和v-show
2017/06/22 Javascript
JS加密插件CryptoJS实现的DES加密示例
2018/08/16 Javascript
js使用formData实现批量上传
2020/03/27 Javascript
vue实现多条件和模糊搜索功能
2019/05/28 Javascript
微信小程序 可搜索的地址选择实现详解
2019/08/28 Javascript
JavaScript this关键字指向常用情况解析
2020/09/02 Javascript
[47:35]VP vs Pain 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/20 DOTA
在Python操作时间和日期之asctime()方法的使用
2015/05/22 Python
在Python的Django框架中编写编译函数
2015/07/20 Python
详解python函数传参是传值还是传引用
2018/01/16 Python
详解python3中的真值测试
2018/08/13 Python
Python3.4解释器用法简单示例
2019/03/22 Python
Python读取xlsx文件的实现方法
2019/07/04 Python
Pytorch之卷积层的使用详解
2019/12/31 Python
python opencv如何实现图片绘制
2020/01/19 Python
司法助理专业自荐书
2014/06/13 职场文书
宣传活动总结范文
2014/07/01 职场文书
2014年大学生村官工作总结
2014/11/19 职场文书
公司趣味运动会开幕词
2016/03/04 职场文书
曾国藩励志经典名言37句,蕴含哲理
2019/10/14 职场文书
Python3中PyQt5简单实现文件打开及保存
2021/06/10 Python
JavaWeb 入门:Hello Servlet
2021/07/16 Java/Android