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 相关文章推荐
jquery解析xml字符串示例分享
Mar 25 Javascript
js面向对象编程之如何实现方法重载
Jul 02 Javascript
jQuery+jRange实现滑动选取数值范围特效
Mar 14 Javascript
tuzhu_req.js 实现仿百度图片首页效果
Aug 11 Javascript
基于javascript实现tab切换特效
Mar 29 Javascript
jQuery实现查找最近父节点的方法
Jun 23 Javascript
简单理解js的prototype属性及使用
Dec 07 Javascript
详解Jquery EasyUI tree 的异步加载(遍历指定文件夹,根据文件夹内的文件生成tree)
Feb 11 Javascript
JS完成画圆圈的小球
Mar 07 Javascript
详解react native页面间传递数据的几种方式
Nov 07 Javascript
详解基于原生JS验证表单组件xy-form
Aug 20 Javascript
javascript json对象小技巧之键名作为变量用法分析
Nov 11 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防盗链的常用方法小结
2010/07/02 PHP
一个PHP针对数字的加密解密类
2014/03/20 PHP
destoon复制新模块的方法
2014/06/21 PHP
PHP统计当前在线用户数实例讲解
2015/10/21 PHP
Yii遍历行下每列数据的方法
2016/10/17 PHP
JavaScript 版本自动生成文章摘要
2008/07/23 Javascript
javascript语言结构小记(一)
2011/09/10 Javascript
JS获取及设置TextArea或input文本框选择文本位置的方法
2015/03/24 Javascript
javascript实现html页面之间参数传递的四种方法实例分析
2015/12/15 Javascript
基于jquery实现动态竖向柱状条特效
2016/02/12 Javascript
JavaScript知识点总结(十一)之js中的Object类详解
2016/05/31 Javascript
jQuery ajax方法传递中文时出现中文乱码的解决方法
2016/07/25 Javascript
微信小程序组件 marquee实例详解
2017/06/23 Javascript
react.js使用webpack搭配环境的入门教程
2017/08/14 Javascript
Echarts.js无法引入问题解决方案
2020/10/30 Javascript
[03:05]《我与DAC》之xiao8:DAC与BG
2018/03/27 DOTA
对python中的xlsxwriter库简单分析
2018/05/04 Python
python删除文本中行数标签的方法
2018/05/31 Python
python conda操作方法
2019/09/11 Python
Python for循环与getitem的关系详解
2020/01/02 Python
利用HTML5 Canvas API绘制矩形的超级攻略
2016/03/21 HTML / CSS
详解如何解决使用JSON.stringify时遇到的循环引用问题
2021/03/23 Javascript
《雾凇》教学反思
2014/02/17 职场文书
美化环境标语
2014/06/20 职场文书
优秀应届毕业生自荐书
2014/06/29 职场文书
教师三严三实学习心得体会
2014/10/11 职场文书
2015年班级工作总结范文
2015/04/03 职场文书
2015年置业顾问工作总结
2015/04/07 职场文书
感恩教育观后感
2015/06/17 职场文书
培训班开班主持词
2015/07/02 职场文书
新学期感想
2015/08/10 职场文书
商业计划书范文
2019/04/24 职场文书
MySQL系列之九 mysql查询缓存及索引
2021/07/02 MySQL
Mysql 8.x 创建用户以及授予权限的操作记录
2022/04/18 MySQL
MySQL脏读,幻读和不可重复读
2022/05/11 MySQL
使用opencv-python如何打开USB或者笔记本前置摄像头
2022/06/21 Python