node.js使用stream模块实现自定义流示例
程序员文章站
2022-03-20 17:41:41
本文实例讲述了node.js使用stream模块实现自定义流。分享给大家供大家参考,具体如下:有些时候我们需要自定义一些流,来操作特殊对象,node.js中为我们提供了一些基本流类。我们新创建的流类需...
本文实例讲述了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程序设计有所帮助。
上一篇: 设计模式:抽象工厂模式,结合类图秒懂!
下一篇: ECharts 地图绘制与钻取简易接口