• 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);
    

      

  • 相关阅读:
    手机屏幕边缘发黄(抢救处理)
    Error parsing HTTP request header 错误解决方法
    SpringBoot项目部署到外部Tomcat重复启动的解决方法
    手机文件管理中网络邻居的使用方法
    解决Tomcat启动过程中报错org.springframework.jmx.export.UnableToRegisterMBeanException
    SpringBoot打成war包后Tomcat无法访问静态资源问题
    Springboot如何使用外部tomcat容器
    Maven打包并入本地jar包
    Excel小技巧之VLOOKUP()使用简单说明
    java.io.IOException: Server returned HTTP response code: 403 for URL
  • 原文地址:https://www.cnblogs.com/jkko123/p/10240574.html
Copyright © 2020-2023  润新知