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实现图片产生波纹一样flash效果的方法
Feb 27 Javascript
简单介绍JavaScript数据类型之隐式类型转换
Dec 28 Javascript
JavaScript中数组的22种方法必学(推荐)
Jul 20 Javascript
JavaScript实现简易的天数计算器实例【附demo源码下载】
Jan 18 Javascript
es6学习之解构时应该注意的点
Aug 29 Javascript
javascript计算对象长度的方法
Oct 25 Javascript
微信小程序显示倒计时功能示例【测试可用】
Dec 03 Javascript
vue里如何主动销毁keep-alive缓存的组件
Mar 21 Javascript
bootstrap中的导航条实例代码详解
May 20 Javascript
了解重排与重绘
May 29 Javascript
JS自定义右键菜单实现代码解析
Jul 16 Javascript
详解gantt甘特图可拖拽、编辑(vue、react都可用 highcharts)
Nov 27 Vue.js
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
咖啡因含量是由谁决定的?低因咖啡怎么来?低因咖啡适合什么人喝
2021/03/06 新手入门
上传多个文件的PHP脚本
2006/11/26 PHP
整理的9个实用的PHP库简介和下载
2010/11/09 PHP
PHP Swoole异步读取、写入文件操作示例
2019/10/24 PHP
jQuery学习笔记之jQuery的动画
2010/12/22 Javascript
jQuery使用ajaxSubmit()提交表单示例
2014/04/04 Javascript
node.js中的http.createClient方法使用说明
2014/12/15 Javascript
IE下支持文本框和密码框placeholder效果的JQuery插件分享
2015/01/31 Javascript
深入理解JavaScript系列(45):代码复用模式(避免篇)详解
2015/03/04 Javascript
Backbone.js的Hello World程序实例
2015/06/19 Javascript
Vue 实现拖动滑块验证功能(只有css+js没有后台验证步骤)
2018/08/24 Javascript
基于vue-router 多级路由redirect 重定向的问题
2018/09/03 Javascript
vue 强制组件重新渲染(重置)的两种方案
2019/10/29 Javascript
原生js实现的观察者和订阅者模式简单示例
2020/04/18 Javascript
[04:49]期待西雅图之战 2016国际邀请赛中国区预选赛WINGS战队赛后采访
2016/06/29 DOTA
python基础教程之面向对象的一些概念
2014/08/29 Python
Python列表和元组的定义与使用操作示例
2017/07/26 Python
对python mayavi三维绘图的实现详解
2019/01/08 Python
python实现植物大战僵尸游戏实例代码
2019/06/10 Python
python rsa实现数据加密和解密、签名加密和验签功能
2019/09/18 Python
Python基本语法之运算符功能与用法详解
2019/10/22 Python
基于Python实现粒子滤波效果
2020/12/01 Python
Python 爬虫批量爬取网页图片保存到本地的实现代码
2020/12/24 Python
css3实现圆锥渐变conic-gradient效果
2020/02/12 HTML / CSS
鲜为人知的HTML5语音合成功能
2019/05/17 HTML / CSS
eBay法国购物网站:eBay.fr
2017/10/21 全球购物
英国网上自行车商店:Tredz Bikes
2019/10/29 全球购物
局部内部类是否可以访问非final变量?
2013/04/20 面试题
厨师岗位职责
2013/11/12 职场文书
电话销售经理岗位职责
2013/12/07 职场文书
银行学习十八大感想
2014/01/11 职场文书
会计专业大学生职业生涯规划范文
2014/01/11 职场文书
单位人事专员介绍信
2014/01/11 职场文书
集中整治工作方案
2014/05/01 职场文书
管理建议书范文
2014/05/13 职场文书
25句企业管理语录:助你迅速打开思路,句句经典!
2020/01/14 职场文书