node.js 条件流管道

node.js conditional stream pipe

我正在尝试了解如何最好地有条件地将流传输到 Transform 或类似 而无需 使用第 3 方库。

理想情况下我想做这样的事情

const transformA, transformB = // my transforms
const booleanA, booleanB = // my various conditions

const stream = new Readable()
stream.push('...') // my content

return stream
         .pipe(booleanA && transformA)
         .pipe(booleanB && transformB)

我尝试过使用像 detour-streamternary-stream 和其他库这样的库,但是我遇到了各种奇怪的副作用,其中转换在不应该被调用时被调用,抛出错误等,这让我想知道人们如何在不增加这些库的复杂性的情况下完成这类事情。

在此期间,我通过采用命令式方法解决了这个问题,在每个条件下重新分配流。

let stream = // get my stream

if (condition) stream = stream.pipe(someTransform)
if (otherCondition) stream = stream.pipe(otherTransform)

return stream

这很好,但我仍然很好奇是否可以实现不可变和函数式方法

感谢观看和阅读

不幸的是,没有对条件管道的内置支持,没有任何第三方模块的替代方法是使用 .pipeline

const stream = require('stream');
const pipeline = util.promisify(stream.pipeline);

const read = new stream.Readable()

const pipes = [
  booleanA && transformA,
  booleanB && transformB
].filter(Boolean); // remove empty pipes

await pipeline(
   read,
   ...pipes
);

由于 .pipeline 采用 N 个转换流,您可以使用已经过滤的管道数组中的扩展运算符。

如果您想 return 最后一个管道流,您可以删除 pipeline 的 promisify 版本。

return pipeline(
   read,
   ...pipes,
   () => {}
)