来自异步生成器和选项的流转换器

Stream transformer from async generator and options

Nodejs 流支持从异步生成器函数生成转换流。正如文档所述:

async generators are effectively a first-class language-level stream construct at this point1

const tf = stream.Duplex.from(async function* (source) {
  for await (const chunk of source)
    yield chunk;
});

但是,它似乎不支持任何 options 参数,这与许多其他流构造方法相反。例如。 objectMode 显然被硬编码为 true2,但类似的问题出现了,例如highWaterMark。文档状态:

Attempting to switch an existing stream into object mode is not safe3

(与关闭它无关)

因此缺少的 options 参数让我感到困惑。

也许有一些原因,为什么这样的流应该始终处于对象模式,但我没有看到它们。类似于例如可读流,像下面这样的转换器对我来说非常有意义(用于演示目的的 xor 操作,想象一下,例如 deflate):

const tf = stream.Duplex.from(async function* (source) {
  for await (const chunk of source) {
    for (let i = 0; i < chunk.length; i++) chunk[i] ^= 0x7C;
    yield chunk;
  }
});

我也没有发现添加 options 参数有任何潜在困难。因此:

以这种方式创建流时,是否可以更改选项? (如果不是,为什么?)

使用Duplex.fromReadable.from时的执行路径在node source code. The implementation for how Duplexes are created from various data sources is here.

中硬编码为highWaterMark: 1objectMode: true

请注意,使用 .from() 不会改变流的源是(异步)生成器,并且生成器一次处理一个数据块并且 运行 直到产生。因此,设置 highWaterMark > 1 就像在生成器中引入一个数组,该数组先发制人地消耗要处理的项目。这根本不符合逻辑。相反,生成器应该按顺序处理可迭代对象中的项目,一次一个。

同样的论点适用于 objectMode: true。生成器按顺序处理可迭代项,而不是从字节缓冲区中读取块。生成器接收这些项目作为输入,而不是从缓冲区中获取一大块字节。

因此,对于输入为连续字节流的 use-cases,可以改用 lower-level API stream.Readablestream.Writablestream.Duplex.