数据API 产品矩阵 案例 关于
掌握聚合最新动态了解行业最新趋势
API接口,开发服务,免费咨询服务

深入理解 Node Stream 内部机制

文章来自公众号:小胡子哥

相信很多人对 Node 的 Stream 已经不陌生了,不论是请求流、响应流、文件流还是 socket 流,这些流的底层都是使用 stream 模块封装的,甚至我们平时用的最多的 console.log 打印日志也使用了它,不信你打开 Node 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 中其他很多模块理解起来就顺畅多了。

本文代码和图片可以在这里取用:https://github.com/barretlee/dive-into-node-stream

stream 模块

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

  • 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. });

这个模式的流程图如下:

1680-640.jpg.jpg

资源的数据流并不是直接流向消费者,而是先 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.<

    声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com

掌握聚合最新动态了解行业最新趋势
API接口,开发服务,免费咨询服务
深入理解 Node Stream 内部机制
发布:2017-06-07 10:45:10

文章来自公众号:小胡子哥

相信很多人对 Node 的 Stream 已经不陌生了,不论是请求流、响应流、文件流还是 socket 流,这些流的底层都是使用 stream 模块封装的,甚至我们平时用的最多的 console.log 打印日志也使用了它,不信你打开 Node 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 中其他很多模块理解起来就顺畅多了。

本文代码和图片可以在这里取用:https://github.com/barretlee/dive-into-node-stream

stream 模块

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

  • 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. });

这个模式的流程图如下:

1680-640.jpg.jpg

资源的数据流并不是直接流向消费者,而是先 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.<

    声明:所有来源为“聚合数据”的内容信息,未经本网许可,不得转载!如对内容有异议或投诉,请与我们联系。邮箱:marketing@think-land.com

选择想要的接口, 看看能免费获取多少次调用 选择(单选)或填写想要的接口
  • 短信API服务
  • 银行卡四元素检测[简]
  • 身份证实名认证
  • 手机状态查询
  • 三网手机实名制认证[简]
  • 身份证OCR识别
  • 证件识别
  • 企业工商信息
短信API服务
  • 短信API服务
  • 银行卡四元素检测[简]
  • 身份证实名认证
  • 手机状态查询
  • 三网手机实名制认证[简]
  • 身份证OCR识别
  • 证件识别
  • 企业工商信息
  • 确定
选择您的身份
请选择寻找接口的目的
预计每月调用量
请选择预计每月调用量
产品研发的阶段
请选择产品研发的阶段
电话 0512-88869195
×
企业用户认证,
可获得1000次免费调用
注册登录 > 企业账户认证 > 领取接口包
企业用户认证领取接口包 立即领取
× 企业用户认证,
可获得1000次免费调用,立即领取>
数 据 驱 动 未 来
Data Drives The Future