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 有何不同?的主要内容,如果未能解决你的问题,请参考以下文章