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实现单继承和多继承的简单方法
Mar 29 Javascript
jQuery拖动图片删除示例
May 10 Javascript
12种不宜使用的Javascript语法整理
Nov 04 Javascript
js和jquery中循环的退出和继续学习记录
Sep 06 Javascript
jQuery中Ajax的get、post等方法详解
Jan 20 Javascript
微信小程序使用第三方库Immutable.js实例详解
Sep 27 Javascript
JS小数转换为整数的方法分析
Jan 07 Javascript
vue项目实现表单登录页保存账号和密码到cookie功能
Aug 31 Javascript
Vue父子组件之间的通信实例详解
Sep 28 Javascript
vue实现手机端省市区区域选择
Sep 27 Javascript
js实现图片上传到服务器和回显
Jan 19 Javascript
Vue中computed及watch区别实例解析
Aug 01 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定时执行计划任务的多种方法小结
2011/12/19 PHP
PHP应用JSON技巧讲解
2013/02/03 PHP
PHP 基于Yii框架中使用smarty模板的方法详解
2013/06/13 PHP
PHP常用函数之base64图片上传功能详解
2019/10/21 PHP
javascript中日期转换成时间戳的小例子
2013/03/21 Javascript
jquery鼠标停止移动事件
2013/12/21 Javascript
网站内容禁止复制和粘贴、另存为的js代码
2014/02/26 Javascript
jquery获取对象的方法足以应付常见的各种类型的对象
2014/05/14 Javascript
用javascript关闭本窗口技巧小结
2014/09/05 Javascript
javascript中Object使用详解
2015/01/26 Javascript
JavaScript创建对象的方式小结(4种方式)
2015/12/17 Javascript
JavaScript数组的栈方法与队列方法详解
2016/05/26 Javascript
js省市县三级联动效果实例
2020/04/15 Javascript
js跨域资源共享 基础篇
2016/07/02 Javascript
js输入框使用正则表达式校验输入内容的实例
2017/02/12 Javascript
BootStrap表单验证 FormValidation 调整反馈图标位置的实例代码
2017/05/17 Javascript
node.js 中间件express-session使用详解
2017/05/20 Javascript
Angular 4 指令快速入门教程
2017/06/07 Javascript
vue.js声明式渲染和条件与循环基础知识
2017/07/31 Javascript
node.js 用socket实现聊天的示例代码
2017/10/17 Javascript
基于Bootstrap下拉框插件bootstrap-select使用方法详解
2018/08/07 Javascript
vue2 设置router-view默认路径的实例
2018/09/20 Javascript
nodejs开发一个最简单的web服务器实例讲解
2020/01/02 NodeJs
Vue-resource安装过程及使用方法解析
2020/07/21 Javascript
gearman的安装启动及python API使用实例
2014/07/08 Python
Python fileinput模块使用介绍
2014/11/30 Python
Python中一行和多行import模块问题
2018/04/01 Python
python批量修改图片尺寸,并保存指定路径的实现方法
2019/07/04 Python
Python中的类与类型示例详解
2019/07/10 Python
利用python-docx模块写批量生日邀请函
2019/08/26 Python
Python代码一键转Jar包及Java调用Python新姿势
2020/03/10 Python
校园公益广告语
2014/03/13 职场文书
精神文明建设先进工作者事迹材料
2014/05/02 职场文书
公司介绍信范文
2015/01/31 职场文书
承德避暑山庄导游词
2015/02/03 职场文书
mysql数据库如何转移到oracle
2022/12/24 MySQL