Node.js 中的 Streams3 是啥,它与 Streams2 有何不同?

Posted

技术标签:

【中文标题】Node.js 中的 Streams3 是啥,它与 Streams2 有何不同?【英文标题】:What is Streams3 in Node.js and how does it differ from Streams2?Node.js 中的 Streams3 是什么,它与 Streams2 有何不同? 【发布时间】:2014-02-27 14:45:49 【问题描述】:

我经常听说 Streams2 和 old-streams,但 Streams3 是什么? It get mentioned in this talk by Thorsten Lorenz.

我在哪里可以了解它,Streams2 和 Streams3 之间有什么区别。

在谷歌上搜索,我也看到Changelog of Node 0.11.5中提到过,

stream:简化流动的被动数据监听 (streams3) (isaacs)

【问题讨论】:

关于流 1、2 和 3 的精彩文章:medium.com/the-node-js-collection/… 【参考方案1】:

我打算试一试,但我可能弄错了。从来没有写过 Streams1(旧流)或 Streams2,我可能不是自我回答这个问题的合适人选,但它就是这样。似乎 Streams1 API 在某种程度上仍然存在。在 Streams2 中,流有两种模式流动(遗留)和非流动。简而言之,支持流动模式的垫片正在消失。这是message that lead to the patch now called called Streams3

与streams2 相同的API,但消除了流动/旧的混乱模式 模式切换。

    每次调用read() 并返回一些数据时,都会触发一个数据事件。 resume() 将使其重复调用 read()。否则,没有变化。 pause() 将使其停止重复调用 read()pipe(dest)on('data', fn) 会自动调用resume()。 没有切换到旧模式。只有流动,停顿。直播开始时已暂停。

不幸的是,要理解任何很好地定义 Streams3 的描述,您需要首先了解 Streams1 和遗留流

背景故事

首先,让我们看一下 Node v0.10.25 文档对这两种模式的说法,

可读流有两种“模式”:流动模式和非流动模式。在流动模式下,数据会从底层系统中读取并尽快提供给您的程序。在非流动模式下,您必须显式调用 stream.read() 以获取数据块。 — Node v0.10.25 Docs

Isaac Z. Schlueter said in November slides I dug up:

流2

“吸流” 调用 read() 从源中提取数据,而不是喷出“数据”事件 解决所有问题(我们知道的)

看起来好像在streams1 中,您会创建一个对象并将.on('data', cb) 调用到该对象。这会将事件设置为触发,然后您将受到流的摆布。在 Streams2 内部,流具有缓冲区,您可以显式地从这些流中请求数据(使用 `.read)。 Isaac 继续指定 Streams2 中的向后兼容如何工作以保持 Streams1(旧流)模块正常运行

旧模式流1 shim

新的流可以切换到旧模式,在那里它们会喷出“数据” 如果添加“数据”事件处理程序,或调用 pause() 或 resume(),则切换 对现有测试进行最小的更改以保持我们的诚实

所以在 Streams2 中,对 .pause().resume() 的调用会触发填充程序。而且,它应该,对吧?在 Streams2 中,您可以控制何时使用.read(),并且您不会发现有人向您扔东西。这触发了独立于 Streams2 的传统模式。

让我们以 Isaac 的幻灯片为例,

createServer(function(q,s) 
  // ADVISORY only!
  q.pause()
  session(q, function(ses) 
    q.on('data', handler)
    q.resume()
  )
)
在 Streams1 中,q 立即开始读取和发送(可能会丢失数据),直到调用 q.pause 建议 q 停止拉入数据,但不停止发送事件以清除它已经读取的内容。 在 Streams2 中,q 开始暂停,直到调用 .pause() 表示模拟旧模式。 在 Streams3 中,q 以暂停状态开始,从未从文件句柄中读取,使 q.pause() 成为 noop,在调用 q.on('data', cb) 时将调用 q.resume,直到缓冲区中没有更多数据.然后再次拨打q.resume 做同样的事情。

【讨论】:

我认为您的第一个要点是错误的。调用 read() 根本不会触发事件,流仍处于暂停模式,并且您可以获得所需的字节数。将处理程序添加到 'data' 事件这一事实会将流切换到流动模式,并且您将开始获取数据事件,直到完成为止。【参考方案2】:

我建议你阅读文档,更具体地说是“API for Stream Consumers”部分,它实际上非常容易理解,此外我认为另一个答案是错误的:http://nodejs.org/api/stream.html#stream_readable_read_size

【讨论】:

【参考方案3】:

似乎 Streams3 是在 io.js 中引入的,然后是在 Node 0.11+ 中引入的

Streams 1 支持的数据被推送到流中。没有消费者控制,无论是否准备好,数据都会被扔给消费者。

Streams 2 允许按照 Streams 1 将数据推送到流中,或者让消费者根据需要从流中提取数据。消费者可以在拉模式下控制数据流(在收到可用数据通知时使用 stream.read())。流不能同时支持推拉。

Streams 3 允许在同一流上拉取和推送数据。

这里有很好的概述:

https://strongloop.com/strongblog/whats-new-io-js-beta-streams3/

缓存版本(2020 年 8 月访问)在这里:https://hackerfall.com/story/whats-new-in-iojs-10-beta-streams-3

【讨论】:

引用的链接已失效。

以上是关于Node.js 中的 Streams3 是啥,它与 Streams2 有何不同?的主要内容,如果未能解决你的问题,请参考以下文章

node.js 中的 Haste 模块映射是啥?

从 Node.js 中的模块导出函数的语法是啥?

node.js中的+new Date语法是啥[重复]

在 node.js 中的数组内查找字符串的最佳方法是啥?

从 node.js 和 Typescript 中的动态文件名加载 JSON 的最佳方法是啥?

Node.js Connect session() 参数中的安全选项是啥