node.js使用stream模块实现自定义流示例

 更新时间:2020年02月13日 08:30:57   作者:怀素真  
这篇文章主要介绍了node.js使用stream模块实现自定义流,结合实例形式详细分析了node.js基于stream模块实现自定义的可读流、可写流、可读写流等相关操作技巧,需要的朋友可以参考下

本文实例讲述了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程序设计有所帮助。

相关文章

  • 搭建一个Koa后端项目脚手架的方法步骤

    搭建一个Koa后端项目脚手架的方法步骤

    这篇文章主要介绍了搭建一个Koa后端项目脚手架的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • Nodejs基于Windows安装步骤

    Nodejs基于Windows安装步骤

    这篇文章主要介绍了Nodejs基于Windows安装步骤,本文分步骤结合图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01
  • nvm安装使用及常用命令

    nvm安装使用及常用命令

    nvm主要是用来管理 nodejs 和 npm 版本的工具,可以用来切换不同版本的 nodejs,这篇文章主要介绍了nvm安装与使用,需要的朋友可以参考下
    2023-01-01
  • nvm安装方法以及安装后node不能使用解决

    nvm安装方法以及安装后node不能使用解决

    在我们的日常开发中经常会遇到这种情况,手上有好几个项目,每个项目的需求不同,进而不同项目必须依赖不同版的NodeJS运行环境,nvm应运而生,这篇文章主要给大家介绍了关于nvm安装方法以及安装后node不能使用解决的相关资料,需要的朋友可以参考下
    2023-04-04
  • nodejs使用node-xlsx生成excel的方法示例

    nodejs使用node-xlsx生成excel的方法示例

    这篇文章主要介绍了nodejs使用node-xlsx生成excel,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • 深入解析nodejs HTTP服务

    深入解析nodejs HTTP服务

    本篇文章主要介绍了深入解析nodejs HTTP服务,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Node在Controller层进行数据校验的过程详解

    Node在Controller层进行数据校验的过程详解

    这篇文章主要给大家介绍了关于Node在Controller层进行数据校验的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • 详解如何查看node端口被占用并杀死

    详解如何查看node端口被占用并杀死

    这篇文章主要给大家介绍了如何查看node端口被占用并杀死,文中给出了相关的解决方法,并通过代码示例给大家介绍的非常详细,对前端开发要学会如何查看端口占用并杀死非常有用,需要的朋友可以参考下
    2024-01-01
  • node.js(express)中使用Jcrop进行图片剪切上传功能

    node.js(express)中使用Jcrop进行图片剪切上传功能

    最近在项目开发中遇到了这样的需求就是要实现用户上传头像,并且要保存用户裁切后的部分作为用户头像。下面给大家分享node.js(express)中使用Jcrop进行图片剪切上传功能,需要的的朋友参考下吧
    2017-04-04
  • Express下采用bcryptjs进行密码加密的方法

    Express下采用bcryptjs进行密码加密的方法

    本篇文章主要介绍了Express下采用bcryptjs进行密码加密的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02

最新评论