大白話說一說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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章