大白话说一说node的stream

在看koa-body的时候,发现很多和流相关的操作,就去看了下node文档和其他文章, 花了挺长时间看完以后发现还只是略知一二,分享记录一下。很多细节还是要看官方文档。

stream是个啥

个人理解,就是个可以控制读写速度的缓冲区的封装,方便大家处理数据,比如说我要读取一个文件,我如果直接使用fs.readFile,不管同步异步吧,总是一口气读出来的,那么同步操作会阻塞,异步操作的话至少文件比较大的时候占的缓存空间是很多的。聪明的你会说,那还可以用fs.read呀,可以自己设置偏移量,自由度很高。是的,不过如果偷懒不想写偏移相关的逻辑的话,你就可以直接使用fs.createReadStream来操作,它可以帮助你最小化内存成本。

读取是这样,写入也是一样的。

而node提供的stream模块,其实就是来帮助我们自己开发一些类似fs.createReadStream这样的自定义的功能。node也有很多封装好的stream,fs.createReadStream显然就是一例,然后http模块的req和res也是,还有很多。而一般上来就直接拿stream模块来使用的,不多,大多是继承它。

纯属个人理解,可能不太准确,如果看了下面一堆东西感觉没明白,请再看一遍上面这段话。

到底读还是写

stream文档上来就跟你说,我们有四种,可读流、可写流、双工流、转换流

不管后面两种不知道在说什么的流,先看可读流和可写流是怎么回事,可读流到底是要读还是要写,先看一个例子。

const Readable = require("stream").Readable;

class ToReadable extends Readable {
  constructor(num) {
    super();
    this.num = num;
  }

  // 生产数据的逻辑
  _read() {
    if (this.num <= 0) {
      // push(null)表示没有数据了
      return this.push(null);
    }
    setTimeout(() => {
      // 通过push方法将数据添加到流中
      this.push("" + this.num--);
    }, 500);
    // 同步调用也一样的
    // this.push("" + this.num--);
  }
}

const readable = new ToReadable(10);

// 监听`data`事件,一次获取一个数据
readable.on("data", data => console.log(data.toString()));

// 所有数据均已读完
readable.on("end", () => console.log("DONE"));

运行一下看看,然后体会一下就会发现,可读流,其实是要开发某个自定义模块的人(一般就是你了)做push数据操作,让使用自定义模块的人可以从模块读数据,可写流,显然就是反过来,用模块的人写数据,开发模块的人(你),读数据,看一个可写流的例子。

const Writable = require("stream").Writable;

const writable = Writable();
writable._write = function(data, enc, callback) {
  console.log(data.toString().toUpperCase());
  // 写入完成时,调用next方法通知流传入下一个数据
  process.nextTick(callback);
  // 同步调用也一样的
  // callback();
};

// 数据写入完毕
writable.on("finish", () => console.log("DONE"));

// 将数据写入流中
writable.write("a");
writable.write("b");
writable.write("c");

// 数据写入结束,需要调用end方法
writable.end();

理解了可读和可写以后,双工和转换其实就容易了。

因为细节很多而且自己一知半解所以不说太多,有兴趣深入了解的,大家可以自己看文档或者其他文章

参考文章:

http://nodejs.cn/api/stream.html#stream_readable_read_size
https://tech.meituan.com/2016/07/08/stream-basics.html
https://tech.meituan.com/2016/07/15/stream-internals.html

你可能感兴趣的:(javascript)