在NodeJS中克隆变换流

时间:2014-08-21 13:12:08

标签: node.js stream

我尝试在几个可读流中重复使用几个转换流(类似gulp,即concat()uglify())。我只能访问创建的实例而不是原始子类。

它没有开箱即用,当我将两个不同的可读流传输到我的变换中时,我得到Error: stream.push() after EOF。不知何故,事件似乎从一个流泄漏到另一个流。

我试图以某种方式干净地设置cloneTransform函数" fork"分为两个区别变换,但我不能让它不分享事件:

function cloneTransform(transform) { var ts = new Transform({objectMode: true}); ts._transform = transform._transform.bind(ts); if(typeof transform._flush !== 'undefined') { ts._flush = transform._flush.bind(ts); } return ts; }

任何替代想法,现有的插件或解决方案来解决这个问题?


更新:上下文

我正在重写gulp-usemin包,它是托管here: gulp-usemin-stream,示例使用here

基本上,你解析一个index.html,寻找围绕样式/脚本声明的注释块,并且你想对这些文件应用几个可配置的转换(参见grunt-usemin)。 所以我试图解决的问题是重用一个变换数组[concat(), uglify()],它们作为选项传递给gulp元变换。

2 个答案:

答案 0 :(得分:1)

你在代码中做了不必要的工作。它应该简单:

function clone(transform) {
  var ts = new Transform({ objectMode: true})
  ts._transform = transform._transform
  ts._flush = transform._flush
  return ts
}

然而,我不确定你是如何使用它的,所以我不确定你得到了什么错误。还有初始化转换流可能用.queue = []或其他东西初始化流的初始化问题,你不会在你的克隆中初始化它。

解决方案完全取决于您尝试解决的问题,我觉得您首先正在接近问题。

答案 1 :(得分:0)

您似乎正在尝试直接使用Transform流而不是对其进行子类化。您应该做的是继承Transform并覆盖_tranform和可选的_flush方法。这样,您就可以为需要使用它的每个可读流创建转换流的新实例。

示例:

var util = require('util');
var Transform = require('stream').Transform;

function MyTransform(options) {
    Transform.call(this, options);
    // ... any setup you want to do ...
}
util.inherits(MyTransform, Transform);


MyTransform.protocol._transform = function(chunk, encoding, done) {
    // ... your _transform implementation ...
}

// Optional
MyTransform.protocol._flush = function(done) {
    // ... optional flush implementation ...
}

完成设置后,您只需为要使用它的每个流创建MyTransform的新实例:

var readStream1 = ...
var readStream2 = ...

var transform1 = new MyTransform();
var transform2 = new MyTransform();

readStream1.pipe(transform1).pipe(...);
readStream2.pipe(transform2).pipe(...);