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

2023-12-27  本文已影响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 值代表是写入了目标还是放在了缓冲区:

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!

上一篇 下一篇

猜你喜欢

热点阅读