创建一个使用streams2通过子进程传递数据的流

时间:2013-07-02 08:34:41

标签: node.js

假设我有一个函数BlackBox。 api是这样的(其中|实际上就是管道):

inputStream | BlackBox | outputStream

但是,BlackBox实际上是require('child_process').spawn的包装器,所以实际上它看起来像这样:

inputStream | BlackBox.Writable -> proc.stdin -> proc.stdout -> BlackBox.Readable | outputStream

我可以使用streams1轻松完成此操作,但我想了解streams2以及它是如何更好的。因此,到目前为止,我有以下代码:

var Duplex = require('stream').Duplex
var spawn = require('child_process').spawn
var util = require('util')

util.inherits(BlackBox, Duplex)

function BlackBox () {
  Duplex.call(this)

  // Example process
  this.proc = spawn('convert', ['-', ':-'])

  var that = this
  this.proc.stdout.on('end', function () {
    that.push(null)
  })
}

BlackBox.prototype._write = function (chunk, encoding, callback) {
  return this.proc.stdin.write(chunk, encoding, callback)
}

BlackBox.prototype.end = function (chunk, encoding, callback) {
  return this.proc.stdin.end(chunk, encoding, callback)
}

BlackBox.prototype._read = function (size) {
  var that = this

  this.proc.stdout.on('readable', function () {
    var chunk = this.read(size)
    if (chunk === null)
      that.push('')
    else
      that.push(chunk)
  })
}

我在这里做错了吗?

我主要关注的是readable._read(size)上的文档摘录:

  

当数据可用时,通过调用readable.push(chunk)将其放入读取队列。如果push返回false,那么你应该停止阅读。再次调用_read时,您应该开始推送更多数据。

我如何“停止阅读”?

要清楚,我希望能够处理背压和节流。

1 个答案:

答案 0 :(得分:1)

isaacs基本上是一个例子:https://github.com/isaacs/duplex-passthrough