美文网首页
Node.js文件可读流可写流、drain事件,背压机制

Node.js文件可读流可写流、drain事件,背压机制

作者: 码农私房菜 | 来源:发表于2023-12-27 12:46 被阅读0次

    流是传输数据时常见的思想,就是一部分一部分的传输内容,是文件读写、网络通信的基础概念。
    Node.js 也提供了 stream 的 api,包括 Readable 可读流、Writable 可写流、Duplex 双工流、Transform 转换流。它们分别实现 _read_write_read + _write_transform 方法,来做数据的返回和处理。
    创建 Readable 对象既可以直接调用 Readable api 创建,然后重写_read 方法,也可以继承 Readable 实现一个子类,之后实例化。其他流同理。(Readable 可以很容易的和 generator 结合)
    当读入的速率大于写入速率的时候就会出现“背压”现象,会爆缓冲区导致数据丢失,解决的方式是根据 write 的速率来动态 pauseresume 可读流的速率。
    当调用 writable stream 的 write 方法的时候会返回一个 boolean 值代表是写入了目标还是放在了缓冲区:

    • true: 数据已经写入目标
    • false:目标不可写入,暂时放在缓冲区
      我们可以判断返回 false 的时候就 pause,然后等缓冲区清空了就 resume:
    const rs = fs.createReadStream(src, {
      flags: "r",
      encoding: null,
      fd: null,
      mode: 438,
      autoClose: true,
      start: 0,
      //   end:3,
      highWaterMark: 4,
    });
    const ws = fs.createWriteStream(dst, {
      flags: "w",
      encoding: "utf-8",
      fd: null,
      mode: 438,
      autoClose: true,
      start: 0,
      //   end:3,
      highWaterMark: 4,
    });
    
    rs.on('data', function (chunk) {
        // 判断返回 false 的时候就 pause
        if (ws.write(chunk) === false) {
            rs.pause();
        }
    });
    
    rs.on('end', function () {
        ws.end();
    });
    // 当缓冲区可以继续写入数据时通过drain时间让生产者知到
    ws.on('drain', function () {
        // 缓冲区清空了就 resume
        rs.resume();
    });
    

    这样就能达到根据写入速率暂停和恢复读入速率的功能,解决了背压问题
    流是掌握 IO 绕不过去的一个概念,而背压问题也是流很常见的问题,遇到了数据丢失可以考虑是否发生了背压。希望这篇文章能够帮大家,真正掌握 stream!

    相关文章

      网友评论

          本文标题:Node.js文件可读流可写流、drain事件,背压机制

          本文链接:https://www.haomeiwen.com/subject/ctvrndtx.html