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 相关文章推荐
js验证表单大全
Nov 25 Javascript
javascript[js]获取url参数的代码
Oct 17 Javascript
解决jquery插件冲突的问题
Jan 23 Javascript
jquery显示隐藏input对象
Jul 21 Javascript
实现前后端数据交互方法汇总
Apr 07 Javascript
开启Javascript中apply、call、bind的用法之旅模式
Oct 28 Javascript
js 简易版滚动条实例(适用于移动端H5开发)
Jun 26 Javascript
Vue的轮播图组件实现方法
Mar 03 Javascript
解决angularjs中同步执行http请求的方法
Aug 13 Javascript
详解vue-router传参的两种方式
Sep 10 Javascript
element form 校验数组每一项实例代码
Oct 10 Javascript
vue实践---根据不同环境,自动转换请求的url地址操作
Sep 21 Javascript
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中$_REQUEST、$_POST、$_GET的区别和联系小结
2011/11/23 PHP
Discuz7.2版的faq.php SQL注入漏洞分析
2014/08/06 PHP
跟我学Laravel之配置Laravel
2014/10/15 PHP
三个思路解决laravel上传文件报错:413 Request Entity Too Large问题
2017/11/13 PHP
js 自定义的联动下拉框
2010/02/07 Javascript
jquery根据属性和index来查找属性值并操作
2014/07/25 Javascript
js中字符串编码函数escape()、encodeURI()、encodeURIComponent()区别详解
2016/04/01 Javascript
JQuery给select添加/删除节点的实现代码
2016/04/26 Javascript
JS正则表达式修饰符global(/g)用法分析
2016/12/27 Javascript
Bootstrap风格的zTree右键菜单
2017/02/17 Javascript
JavaScript代码实现txt文件的上传预览功能
2018/03/27 Javascript
element-ui中的select下拉列表设置默认值方法
2018/08/24 Javascript
Cookbook组件形式:优化 Vue 组件的运行时性能
2018/11/25 Javascript
React 全自动数据表格组件——BodeGrid的实现思路
2019/06/12 Javascript
VUE子组件向父组件传值详解(含传多值及添加额外参数场景)
2020/09/01 Javascript
谈谈JavaScript中的函数
2020/09/08 Javascript
Python深入06——python的内存管理详解
2016/12/07 Python
python SSH模块登录,远程机执行shell命令实例解析
2018/01/12 Python
Python 爬取携程所有机票的实例代码
2018/06/11 Python
Windows 平台做 Python 开发的最佳组合(推荐)
2020/07/27 Python
python3环境搭建过程(利用Anaconda+pycharm)完整版
2020/08/19 Python
Python页面加载的等待方式总结
2021/02/28 Python
全面解析CSS Media媒体查询使用操作(推荐)
2017/08/15 HTML / CSS
Agoda台湾官网:国内外订房2折起
2018/03/20 全球购物
什么时候用assert
2015/05/08 面试题
报关简历自我评价怎么写
2013/09/19 职场文书
计算机科学与技术应届生求职信
2013/11/07 职场文书
公益活动策划方案
2014/01/09 职场文书
毕业生自我鉴定实例
2014/01/21 职场文书
婚庆公司的创业计划书
2014/01/22 职场文书
应届护士求职信范文
2014/01/26 职场文书
霸王洗发水广告词
2014/03/14 职场文书
安全生产演讲稿
2014/05/09 职场文书
个人对照检查材料思想汇报(四风问题)
2014/09/25 职场文书
学习十八届四中全会依法治国心得体会
2014/11/03 职场文书
加入学生会自荐书
2015/03/05 职场文书