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 setTimeout()函数使用方法
Apr 07 Javascript
JQuery EasyUI 日期控件如何控制日期选择区间
May 05 Javascript
jquery果冻抖动效果实现方法
Jan 15 Javascript
javascript为按钮注册回车事件(设置默认按钮)的方法
May 09 Javascript
jquery合并表格中相同文本的相邻单元格
Jul 17 Javascript
js密码强度校验
Nov 10 Javascript
深入理解node exports和module.exports区别
Jun 01 Javascript
JavaScript和jQuery获取input框的绝对位置实现方法
Oct 13 Javascript
Angular.js实现动态加载组件详解
May 28 Javascript
vue 中filter的多种用法
Apr 26 Javascript
js 获取扫码枪输入数据的方法
Jun 10 Javascript
vue集成openlayers加载geojson并实现点击弹窗教程
Sep 24 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强制文件下载而非在浏览器打开的自定义函数分享
2014/05/08 PHP
php修改上传图片尺寸的方法
2015/04/14 PHP
php中使用gd库实现远程图片下载实例
2015/05/12 PHP
php获取字符串前几位的实例(substr返回字符串的子串用法)
2017/03/08 PHP
PHP7匿名类的用法示例
2019/04/05 PHP
PHP高并发和大流量解决方案整理
2019/12/24 PHP
js左侧多级菜单动态的解决方案
2010/02/01 Javascript
Dom 是什么的详细说明
2010/10/25 Javascript
Javascript 按位与运算符 (&)使用介绍
2014/02/04 Javascript
jQuery页面加载初始化常用的三种方法
2014/06/04 Javascript
jQuery实现伪分页的方法分享
2016/02/17 Javascript
js初始化验证实例详解
2016/11/26 Javascript
Angular 4 依赖注入学习教程之FactoryProvider的使用(四)
2017/06/04 Javascript
JS实现根据指定值删除数组中的元素操作示例
2018/08/02 Javascript
在element-ui的select下拉框加上滚动加载
2019/04/18 Javascript
浅谈vue 锚点指令v-anchor的使用
2019/11/13 Javascript
详解JavaScript修改注册表的方法
2020/01/05 Javascript
对Python通过pypyodbc访问Access数据库的方法详解
2018/10/27 Python
python 环境搭建 及python-3.4.4的下载和安装过程
2019/07/20 Python
Django模板语言 Tags使用详解
2019/09/09 Python
python命令 -u参数用法解析
2019/10/24 Python
python绘制无向图度分布曲线示例
2019/11/22 Python
使用python快速实现不同机器间文件夹共享方式
2019/12/22 Python
Matplotlib使用字符串代替变量绘制散点图的方法
2020/02/17 Python
Origins加拿大官网:雅诗兰黛集团高端植物护肤品牌
2017/11/19 全球购物
乌克兰排名第一的在线旅游超市:Farvater.Travel
2020/01/02 全球购物
美国电子产品购物网站:BuyDig.com
2020/06/17 全球购物
高级电工工作职责
2013/11/21 职场文书
八一建军节部队活动方案
2014/02/04 职场文书
大学生村官考核材料
2014/05/23 职场文书
工地例会施工汇报材料
2014/08/22 职场文书
晚会开幕词
2015/01/28 职场文书
员工工作表现自我评价
2015/03/06 职场文书
导游词之张家界
2019/10/31 职场文书
导游词之永泰公主墓
2019/12/04 职场文书
MySQL 自定义变量的概念及特点
2021/05/13 MySQL