过滤node.js中的Stream对象

sli*_*lim 6 streaming javascript-events node.js

在我看来,在Node.js中处理某些类型数据的优雅方法是链接处理对象,如UNIX管道.

例如,grep:

function Grep(pattern) {
    ...
}
util.inherits(Grep, stream.Stream);

Grep.prototype.???? = ???????  // What goes here?

grep = new Grep(/foo/);

process.stdin.pipe(grep);
myStream.pipe(process.stdout);
Run Code Online (Sandbox Code Playgroud)

然而,我并不清楚为什么需要重写各种Stream方法才能使其工作.

如何创建简单地从其输入复制到其输出的Stream对象?据推测,更复杂的过滤流变得微不足道.

更新:感觉好像以下应该有效(用CoffeeScript表示,所以我不用JS语法填充这个框!):

class Forwarder extends stream.Stream
    write: (chunk, encoding) ->
        @emit 'data', chunk
    end: (chunk, encoding) =>
        if chunk?
            @emit 'data', chunk
        @emit 'end'

fwd = new Forwarder()
fwd.pipe(process.stdout);
process.stdin.pipe(fwd);
process.stdin.resume();
Run Code Online (Sandbox Code Playgroud)

但是,在此脚本中捕获内容不会输出任何内容.在脚本中显式调用'fwd.write()'会导致stdout输出.

log*_*yth 8

你非常亲密.

因为您使用的是非常低级的流类,所以需要设置流可写属性以使其成为可写流.如果您正在从流中读取,则需要设置可读属性.此结束事件也没有任何参数.

class Forwarder extends stream.Stream
  constructor: ->
    @writable = true
  write: (chunk, encoding) ->
    @emit 'data', chunk
  end: ->
    @emit 'end'

fwd = new Forwarder()
fwd.pipe(process.stdout);
process.stdin.pipe(fwd);
process.stdin.resume();
Run Code Online (Sandbox Code Playgroud)

更新

以上答案适用于Node <= 0.8中的V1流.如果你使用> 0.8,Node已经添加了更多特定的类,这些类被设计为扩展,所以你会使用更像这样的东西:

class Forwarder extends stream.Transform
    _transform: (chunk, encoding, callback) ->
      this.push(chunk);
      callback();
Run Code Online (Sandbox Code Playgroud)

处理chunk和推送你真正想要的碎片.

  • Augh!我花了很长时间调试这个因为我把'可写'而不是'可写'.一定要明白这个词! (7认同)