数据API 案例 开发者 关于
掌握聚合最新动态了解行业最新趋势
API接口,开发服务,免费咨询服务
新闻动态 > 媒体报道

深入理解 Node.js Stream 内部机制

相信很多人对 Node.js 的 Stream 已经不陌生了,不论是请求流、响应流、文件流还是 socket 流,这些流的底层都是使用 stream 模块封装的,甚至我们平时用的最多的 console.log 打印日志也使用了它,不信你打开 Node.js runtime 的源码,看看 lib/console.js:

  1. function write(ignoreErrors, stream, string, errorhandler) {

  2.  // ...

  3.  stream.once('error', noop);

  4.  stream.write(string, errorhandler);

  5.  //...

  6. }

  7. Console.prototype.log = function log(...args) {

  8.  write(this._ignoreErrors,

  9.        this._stdout,

  10.        `${util.format.apply(null, args)}\n`,

  11.        this._stdoutErrorHandler);

  12. };

Stream 模块做了很多事情,了解了 Stream,那么 Node.js 中其他很多模块理解起来就顺畅多了。

stream 模块

如果你了解 生产者和消费者问题 的解法,那理解 stream 就基本没有压力了,它不仅仅是资料的起点和落点,还包含了一系列状态控制,可以说一个 stream 就是一个状态管理单元。了解内部机制的最佳方式除了看 Node.js 官方文档,还可以去看看 Node.js 的 源码:

  • lib/module.js

  • lib/_stream_readable.js

  • lib/_stream_writable.js

  • lib/_stream_tranform.js

  • lib/_stream_duplex.js

把 Readable 和 Writable 看明白,Tranform 和 Duplex 就不难理解了。

Readable Stream

Readable Stream 存在两种模式,一种是叫做 FlowingMode,流动模式,在 Stream 上绑定 ondata 方法就会自动触发这个模式,比如:

  1. const readable = getReadableStreamSomehow();

  2. readable.on('data', (chunk) => {

  3.  console.log(`Received ${chunk.length} bytes of data.`);

  4. });

这个模式的流程图如下:

资源的数据流并不是直接流向消费者,而是先 push 到缓存池,缓存池有一个水位标记 highWatermark,超过这个标记阈值,push 的时候会返回 false,什么场景下会出现这种情况呢?

  • 消费者主动执行了 .pause()

  • 消费速度比数据 push 到缓存池的生产速度慢

有个专有名词来形成这种情况,叫做「背压」,Writable Stream 也存在类似的情况。

流动模式,这个名词还是很形象的,缓存池就像一个水桶,消费者通过管口接水,同时,资源池就像一个水泵,不断地往水桶中泵水,而 highWaterMark 是水桶的浮标,达到阈值就停止蓄水。下面是一个简单的 Demo:

  1. const Readable = require('stream').Readable;

  2. // Stream 实现

  3. class MyReadable extends Readable {

  4.  constructor(dataSource, options) {

  5.    super(options);

  6.    this.dataSource = dataSource;

  7.  }

  8.  // 继承了 Readable 的类必须实现这个函数

  9.  // 触发系统底层对流的读取

  10.  _read() {

  11.    const data = this.dataSource.makeData

    标签/Tag

掌握聚合最新动态了解行业最新趋势
API接口,开发服务,免费咨询服务
新闻动态 > 媒体报道
深入理解 Node.js Stream 内部机制
发布:2017-09-25

相信很多人对 Node.js 的 Stream 已经不陌生了,不论是请求流、响应流、文件流还是 socket 流,这些流的底层都是使用 stream 模块封装的,甚至我们平时用的最多的 console.log 打印日志也使用了它,不信你打开 Node.js runtime 的源码,看看 lib/console.js:

  1. function write(ignoreErrors, stream, string, errorhandler) {

  2.  // ...

  3.  stream.once('error', noop);

  4.  stream.write(string, errorhandler);

  5.  //...

  6. }

  7. Console.prototype.log = function log(...args) {

  8.  write(this._ignoreErrors,

  9.        this._stdout,

  10.        `${util.format.apply(null, args)}\n`,

  11.        this._stdoutErrorHandler);

  12. };

Stream 模块做了很多事情,了解了 Stream,那么 Node.js 中其他很多模块理解起来就顺畅多了。

stream 模块

如果你了解 生产者和消费者问题 的解法,那理解 stream 就基本没有压力了,它不仅仅是资料的起点和落点,还包含了一系列状态控制,可以说一个 stream 就是一个状态管理单元。了解内部机制的最佳方式除了看 Node.js 官方文档,还可以去看看 Node.js 的 源码:

  • lib/module.js

  • lib/_stream_readable.js

  • lib/_stream_writable.js

  • lib/_stream_tranform.js

  • lib/_stream_duplex.js

把 Readable 和 Writable 看明白,Tranform 和 Duplex 就不难理解了。

Readable Stream

Readable Stream 存在两种模式,一种是叫做 FlowingMode,流动模式,在 Stream 上绑定 ondata 方法就会自动触发这个模式,比如:

  1. const readable = getReadableStreamSomehow();

  2. readable.on('data', (chunk) => {

  3.  console.log(`Received ${chunk.length} bytes of data.`);

  4. });

这个模式的流程图如下:

资源的数据流并不是直接流向消费者,而是先 push 到缓存池,缓存池有一个水位标记 highWatermark,超过这个标记阈值,push 的时候会返回 false,什么场景下会出现这种情况呢?

  • 消费者主动执行了 .pause()

  • 消费速度比数据 push 到缓存池的生产速度慢

有个专有名词来形成这种情况,叫做「背压」,Writable Stream 也存在类似的情况。

流动模式,这个名词还是很形象的,缓存池就像一个水桶,消费者通过管口接水,同时,资源池就像一个水泵,不断地往水桶中泵水,而 highWaterMark 是水桶的浮标,达到阈值就停止蓄水。下面是一个简单的 Demo:

  1. const Readable = require('stream').Readable;

  2. // Stream 实现

  3. class MyReadable extends Readable {

  4.  constructor(dataSource, options) {

  5.    super(options);

  6.    this.dataSource = dataSource;

  7.  }

  8.  // 继承了 Readable 的类必须实现这个函数

  9.  // 触发系统底层对流的读取

  10.  _read() {

  11.    const data = this.dataSource.makeData

    电话 0512-88869195