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中的作用域scope介绍
Dec 28 Javascript
js实现杯子倒水问题自动求解程序
Mar 25 Javascript
简介JavaScript中的getUTCFullYear()方法的使用
Jun 10 Javascript
各式各样的导航条效果css3结合jquery代码实现
Sep 17 Javascript
Vue 实现双向绑定的四种方法
Mar 16 Javascript
深入理解Vue 的钩子函数
Sep 05 Javascript
angularjs的单选框+ng-repeat的实现方法
Sep 12 Javascript
webstorm中配置Eslint的两种方式及差异比较详解
Oct 19 Javascript
javascript自定义日期比较函数用法示例
Jul 22 Javascript
js 闭包深入理解与实例分析
Mar 19 Javascript
原生JS实现无缝轮播图片
Jun 24 Javascript
jQuery实现可以计算进制转换的计算器
Oct 19 jQuery
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实现图形显示Ip地址的代码及注释
2014/01/20 PHP
PHP Yii框架之表单验证规则大全
2015/11/16 PHP
PHP实现的构造sql语句类实例
2016/02/03 PHP
PHP程序中的文件锁、互斥锁、读写锁使用技巧解析
2016/03/21 PHP
关于PHP转换超过2038年日期出错的问题解决
2017/06/28 PHP
jQuery EasyUI API 中文文档 - EasyLoader 加载器
2011/09/29 Javascript
extjs关于treePanel+chekBox全部选中以及清空选中问题探讨
2013/04/02 Javascript
JQueryEasyUI Layout布局框架的使用
2013/04/08 Javascript
关于query Javascript CSS Selector engine
2013/04/12 Javascript
用js设置下拉框为只读的小技巧
2014/04/10 Javascript
Javascript监视变量变化的方法
2015/06/09 Javascript
JavaScript数组对象赋值用法实例
2015/08/04 Javascript
jquery实现标题字体变换的滑动门菜单效果
2015/09/07 Javascript
Javascript函数式编程语言
2015/10/11 Javascript
判断JS对象是否拥有某属性的方法推荐
2016/05/12 Javascript
Node.js查找当前目录下文件夹实例代码
2017/03/07 Javascript
微信小程序promsie.all和promise顺序执行
2017/10/27 Javascript
jQuery实现购物车的总价计算和总价传值功能
2018/11/28 jQuery
微信小程序自定义可滑动日历界面
2018/12/28 Javascript
微信小程序中显示倒计时代码实例
2019/05/09 Javascript
Vue.js组件实现选项卡以及切换特效
2019/07/24 Javascript
maptalks+three.js+vue webpack实现二维地图上贴三维模型操作
2020/08/10 Javascript
WebStorm中如何将自己的代码上传到github示例详解
2020/10/28 Javascript
python在windows命令行下输出彩色文字的方法
2015/03/19 Python
Python聚类算法之基本K均值实例详解
2015/11/20 Python
python矩阵的转置和逆转实例
2018/12/12 Python
Python合并2个字典成1个新字典的方法(9种)
2019/12/19 Python
深入浅析Python 函数注解与匿名函数
2020/02/24 Python
解决pycharm每次打开项目都需要配置解释器和安装库问题
2020/02/26 Python
家得宝加拿大家装网上商店:The Home Depot加拿大
2016/08/27 全球购物
美国摄影爱好者购物网站:Focus Camera
2016/10/21 全球购物
欧克利英国官网:Oakley英国
2019/08/24 全球购物
暑假家长评语大全
2014/04/17 职场文书
2015年女工委工作总结
2015/07/27 职场文书
MySQL为数据表建立索引的原则详解
2022/03/03 MySQL
PostgreSQL数据库创建并使用视图以及子查询
2022/04/11 PostgreSQL