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

流是传输数据时常见的思想,就是一部分一部分的传输内容,是文件读写、网络通信的基础概念。
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 的开发人员可能知道,流(Stream)这个概念比较难理解,也不太好处理。 用 Domini...
    1024译站阅读 1,543评论 0 1
  • 流的概念 流是一组有序的、有起点和终点的字节数据传输手段 流不关心文件的整体内容,只关注是否从文件中读到了数据,以...
    alipy_258阅读 176评论 0 2
  • 流是什么? 这个字进入我脑海我第一时间想到的是一句诗,抽刀断水水更流,举杯消愁...额,今天的主角是流。不好意思差...
    duffy990阅读 796评论 0 3
  • 一.node.js中的流是什么 stream(流)是Node.js提供的又一个仅在服务区端可用的模块,流是一种抽象...
    nightZing阅读 6,152评论 4 16
  • stream 流是一个抽象接口,在 Node 里被不同的对象实现。例如 request to an HTTP se...
    明明三省阅读 3,451评论 1 10