节点中的流是什么?它与Streams2有何不同?

时间:2023-01-14 18:29:42

I've often heard of Streams2 and old-streams, but what is Streams3? It get mentioned in this talk by Thorsten Lorenz.

我经常听说过Streams2和旧流,但是Streams3是什么呢?这是托尔斯滕·洛伦茨在这次演讲中提到的。

Where can I read about it, and what is the difference between Streams2 and Streams3.

我在哪里可以看到它,以及Streams2和Streams3的区别。

Doing a search on Google, I also see it mentioned in the Changelog of Node 0.11.5,

在谷歌上进行搜索,我也看到在Changelog节点0.11.5中提到过,

stream: Simplify flowing, passive data listening (streams3) (isaacs)

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

3 个解决方案

#1


41  

I'm going to give this a shot, but I've probably got it wrong. Having never written Streams1 (old-streams) or Streams2, I'm probably not the right guy to self-answer this one, but here it goes. It seems as if there is Streams1 API that still persists to some degree. In Streams2, there are two modes of streams flowing (legacy), and non-flowing. In short, the shim that supported flowing mode is going away. This was the message that lead to the patch now called called Streams3,

我要试一试,但我可能弄错了。我从来没有写过Streams1(老的流)或Streams2,所以我可能不是回答这个问题的合适人选,但它就在这里。似乎仍然存在一定程度的Streams1 API。在Streams2中,有两种类型的流(遗留)和非流动模式。简而言之,支撑流动模式的垫片正在消失。这就是导致现在称为Streams3的补丁的信息,

Same API as streams2, but remove the confusing modality of flowing/old mode switch.

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

  1. Every time read() is called, and returns some data, a data event fires.
  2. 每次调用read()并返回一些数据时,都会触发一个数据事件。
  3. resume() will make it call read() repeatedly. Otherwise, no change.
  4. resume()将重复调用read()。否则,没有变化。
  5. pause() will make it stop calling read() repeatedly.
  6. pause()将使它停止重复调用read()。
  7. pipe(dest) and on('data', fn) will automatically call resume().
  8. 管道(dest)和on('data, fn)将自动调用resume()。
  9. No switches into old-mode. There's only flowing, and paused. Streams start out paused.
  10. 没有开关到旧有模式。只有流动的,停顿了一下。流开始停了下来。

Unfortunately, to understand any of description which defines Streams3 pretty well, you need to first understand Streams1, and the legacy streams

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

Backstory

First, let's take a look at what the Node v0.10.25 docs say about the two modes,

首先,让我们看看节点v0。10.25文档对于这两种模式是怎么说的,

Readable streams have two "modes": a flowing mode and a non-flowing mode. When in flowing mode, data is read from the underlying system and provided to your program as fast as possible. In non-flowing mode, you must explicitly call stream.read() to get chunks of data out.Node v0.10.25 Docs

可读流有两种“模式”:流模式和非流模式。当处于流动模式时,数据从底层系统读取,并尽可能快地提供给程序。在非流动模式中,必须显式地调用stream.read()来获取大量的数据。——节点v0.10.25文档

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

Isaac Z. Schlueter在11月的幻灯片中写道:

streams2

streams2

  • "suck streams"
  • “吸流”
  • Instead of 'data' events spewing, call read() to pull data from source
  • 调用read()来从源中提取数据,而不是“数据”事件的spewing。
  • Solves all problems (that we know of)
  • 解决我们所知道的所有问题

So it seems as if in streams1, you'd create an object and call .on('data', cb) to that object. This would set the event to be trigger, and then you were at the mercy of the stream. In Streams2 internally streams have buffers and you request data from those streams explicitly (using `.read). Isaac goes on to specify how backwards compat works in Streams2 to keep Streams1 (old-stream) modules functioning

因此,在streams1中,似乎要创建一个对象并调用.on('data', cb)到该对象。这将把事件设置为触发器,然后您就在流的支配下了。在Streams2内部流中有缓冲区,您可以显式地从这些流中请求数据(使用' .read)。以撒继续说明了在Streams2中如何向后编译以保持Streams1(旧流)模块的功能。

old-mode streams1 shim

旧型streams1垫片

  • New streams can switch into old-mode, where they spew 'data'
  • 新的流可以切换到旧模式,在那里它们会吐出“数据”
  • If you add a 'data' event handler, or call pause() or resume(), then switch
  • 如果您添加了“data”事件处理程序,或调用pause()或resume(),则切换
  • Making minimal changes to existing tests to keep us honest
  • 对现有的测试进行最小的修改以保持我们的诚实

So in Streams2, a call to .pause() or .resume() triggers the shim. And, it should, right? In Streams2 you have control over when to .read(), and you're not catching stuff being thrown at you. This triggered a legacy mode that acted independently of Streams2.

所以在Streams2中,对.pause()或.resume()的调用触发shim。它应该,对吧?在Streams2中,您可以控制何时.read(),而您并没有捕捉到向您抛出的东西。这触发了独立于Streams2的遗留模式。

Let's take an example from Isaac's slide,

我们以艾萨克的幻灯片为例,

createServer(function(q,s) {
  // ADVISORY only!
  q.pause()
  session(q, function(ses) {
    q.on('data', handler)
    q.resume()
  })
})
  • In Streams1, q starts up right away reading and emitting (likely losing data), until the call to q.pause advises q to stop pulling in data but not from emitting events to clear what it already read.
  • 在Streams1中,q立即开始读取和发送(可能丢失数据),直到调用q。pause建议q停止提取数据,但不要发出事件来清除它已经读取的内容。
  • In Streams2, q starts off paused until the call to .pause() which signifies to emulate the old mode.
  • 在Streams2中,q从暂停开始,直到调用.pause(),这表示模拟旧模式。
  • In Streams3, q starts off as paused having never read from the file handle making the q.pause() a noop, and on the call to q.on('data', cb) will call q.resume until there is no more data in the buffer. And, then call again q.resume doing the same thing.
  • 在Streams3中,q从没有从文件句柄中读取,使q.pause()为noop,并在对q的调用中开始。在(data, cb)上调用q。恢复到缓冲区中没有数据为止。然后再调用q。继续做同样的事情。

#2


6  

Seems like Streams3 was introduced in io.js, then in Node 0.11+

好像在io中引入了Streams3。然后在节点0.11+

Streams 1 Supported data being pushed to a stream. There was no consumer control, data was thrown at the consumer whether it was ready or not.

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

Streams 2 allows data to be pushed to a stream as per Streams 1, or for a consumer to pull data from a stream as needed. The consumer could control the flow of data in pull mode (using stream.read() when notified of available data). The stream can not support both push and pull at the same time.

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

Streams 3 allows pull and push data on the same stream.

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

Great overview here:

伟大的概述:

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

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

#3


-4  

I suggest you read the documentation, more specifically the section "API for Stream Consumers", it's actually very understandable, besides I think the other answer is wrong: http://nodejs.org/api/stream.html#stream_readable_read_size

我建议您阅读文档,特别是“流消费者的API”一节,它实际上是可以理解的,而且我认为另一个答案是错误的:http://nodejs.org/api/stream.html#stream_readable_read_size

#1


41  

I'm going to give this a shot, but I've probably got it wrong. Having never written Streams1 (old-streams) or Streams2, I'm probably not the right guy to self-answer this one, but here it goes. It seems as if there is Streams1 API that still persists to some degree. In Streams2, there are two modes of streams flowing (legacy), and non-flowing. In short, the shim that supported flowing mode is going away. This was the message that lead to the patch now called called Streams3,

我要试一试,但我可能弄错了。我从来没有写过Streams1(老的流)或Streams2,所以我可能不是回答这个问题的合适人选,但它就在这里。似乎仍然存在一定程度的Streams1 API。在Streams2中,有两种类型的流(遗留)和非流动模式。简而言之,支撑流动模式的垫片正在消失。这就是导致现在称为Streams3的补丁的信息,

Same API as streams2, but remove the confusing modality of flowing/old mode switch.

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

  1. Every time read() is called, and returns some data, a data event fires.
  2. 每次调用read()并返回一些数据时,都会触发一个数据事件。
  3. resume() will make it call read() repeatedly. Otherwise, no change.
  4. resume()将重复调用read()。否则,没有变化。
  5. pause() will make it stop calling read() repeatedly.
  6. pause()将使它停止重复调用read()。
  7. pipe(dest) and on('data', fn) will automatically call resume().
  8. 管道(dest)和on('data, fn)将自动调用resume()。
  9. No switches into old-mode. There's only flowing, and paused. Streams start out paused.
  10. 没有开关到旧有模式。只有流动的,停顿了一下。流开始停了下来。

Unfortunately, to understand any of description which defines Streams3 pretty well, you need to first understand Streams1, and the legacy streams

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

Backstory

First, let's take a look at what the Node v0.10.25 docs say about the two modes,

首先,让我们看看节点v0。10.25文档对于这两种模式是怎么说的,

Readable streams have two "modes": a flowing mode and a non-flowing mode. When in flowing mode, data is read from the underlying system and provided to your program as fast as possible. In non-flowing mode, you must explicitly call stream.read() to get chunks of data out.Node v0.10.25 Docs

可读流有两种“模式”:流模式和非流模式。当处于流动模式时,数据从底层系统读取,并尽可能快地提供给程序。在非流动模式中,必须显式地调用stream.read()来获取大量的数据。——节点v0.10.25文档

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

Isaac Z. Schlueter在11月的幻灯片中写道:

streams2

streams2

  • "suck streams"
  • “吸流”
  • Instead of 'data' events spewing, call read() to pull data from source
  • 调用read()来从源中提取数据,而不是“数据”事件的spewing。
  • Solves all problems (that we know of)
  • 解决我们所知道的所有问题

So it seems as if in streams1, you'd create an object and call .on('data', cb) to that object. This would set the event to be trigger, and then you were at the mercy of the stream. In Streams2 internally streams have buffers and you request data from those streams explicitly (using `.read). Isaac goes on to specify how backwards compat works in Streams2 to keep Streams1 (old-stream) modules functioning

因此,在streams1中,似乎要创建一个对象并调用.on('data', cb)到该对象。这将把事件设置为触发器,然后您就在流的支配下了。在Streams2内部流中有缓冲区,您可以显式地从这些流中请求数据(使用' .read)。以撒继续说明了在Streams2中如何向后编译以保持Streams1(旧流)模块的功能。

old-mode streams1 shim

旧型streams1垫片

  • New streams can switch into old-mode, where they spew 'data'
  • 新的流可以切换到旧模式,在那里它们会吐出“数据”
  • If you add a 'data' event handler, or call pause() or resume(), then switch
  • 如果您添加了“data”事件处理程序,或调用pause()或resume(),则切换
  • Making minimal changes to existing tests to keep us honest
  • 对现有的测试进行最小的修改以保持我们的诚实

So in Streams2, a call to .pause() or .resume() triggers the shim. And, it should, right? In Streams2 you have control over when to .read(), and you're not catching stuff being thrown at you. This triggered a legacy mode that acted independently of Streams2.

所以在Streams2中,对.pause()或.resume()的调用触发shim。它应该,对吧?在Streams2中,您可以控制何时.read(),而您并没有捕捉到向您抛出的东西。这触发了独立于Streams2的遗留模式。

Let's take an example from Isaac's slide,

我们以艾萨克的幻灯片为例,

createServer(function(q,s) {
  // ADVISORY only!
  q.pause()
  session(q, function(ses) {
    q.on('data', handler)
    q.resume()
  })
})
  • In Streams1, q starts up right away reading and emitting (likely losing data), until the call to q.pause advises q to stop pulling in data but not from emitting events to clear what it already read.
  • 在Streams1中,q立即开始读取和发送(可能丢失数据),直到调用q。pause建议q停止提取数据,但不要发出事件来清除它已经读取的内容。
  • In Streams2, q starts off paused until the call to .pause() which signifies to emulate the old mode.
  • 在Streams2中,q从暂停开始,直到调用.pause(),这表示模拟旧模式。
  • In Streams3, q starts off as paused having never read from the file handle making the q.pause() a noop, and on the call to q.on('data', cb) will call q.resume until there is no more data in the buffer. And, then call again q.resume doing the same thing.
  • 在Streams3中,q从没有从文件句柄中读取,使q.pause()为noop,并在对q的调用中开始。在(data, cb)上调用q。恢复到缓冲区中没有数据为止。然后再调用q。继续做同样的事情。

#2


6  

Seems like Streams3 was introduced in io.js, then in Node 0.11+

好像在io中引入了Streams3。然后在节点0.11+

Streams 1 Supported data being pushed to a stream. There was no consumer control, data was thrown at the consumer whether it was ready or not.

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

Streams 2 allows data to be pushed to a stream as per Streams 1, or for a consumer to pull data from a stream as needed. The consumer could control the flow of data in pull mode (using stream.read() when notified of available data). The stream can not support both push and pull at the same time.

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

Streams 3 allows pull and push data on the same stream.

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

Great overview here:

伟大的概述:

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

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

#3


-4  

I suggest you read the documentation, more specifically the section "API for Stream Consumers", it's actually very understandable, besides I think the other answer is wrong: http://nodejs.org/api/stream.html#stream_readable_read_size

我建议您阅读文档,特别是“流消费者的API”一节,它实际上是可以理解的,而且我认为另一个答案是错误的:http://nodejs.org/api/stream.html#stream_readable_read_size