14

在 Node v10.11 中,我试图将对象推入管道,但总是出错。

events.js:72
    throw er; // Unhandled 'error' event
          ^
TypeError: Invalid non-string/buffer chunk
    at validChunk (_stream_writable.js:150:14)
    at WriteStream.Writable.write (_stream_writable.js:179:12)

我能做到

this.push(chunk)

直接通过管道传输数据,但我做不到

var result = {'the web content is': chunk}
this.push(result)

30 LOC 中的可运行示例:

var stream = require('stream');

var MsgExtractStream = function() {
  stream.Transform.call(this,{objectMode: true});
}

MsgExtractStream.prototype = Object.create(
  stream.Transform.prototype, {constructor: {value: MsgExtractStream}} )

MsgExtractStream.prototype._transform = function(chunk, encoding, callback) {
  var result = {'the website is': chunk};
  this.push(result);
}

MsgExtractStream.prototype.write = function () {
  this._transform.apply(this, arguments);
};

MsgExtractStream.prototype.end = function () {
  this._transform.apply(this, arguments);
  this.emit("end");
};

var fs = require("fs"),
  inPage = fs.createReadStream("inPage.html"),
  outPage = fs.createWriteStream("outPage.html"),
  msgPage = new MsgExtractStream();

inPage.
pipe(msgPage).
pipe(outPage);
4

1 回答 1

9

你所做的一切都是正确的,除了最后一句话。您正在将 MsgExtractStream 的结果通过管道Transform传输objectMode到一个简单的流中。

管道时,您从 msgPage 读取内容,获取对象,然后将它们写入 outPage。但是 outPage 没有objectModeon,因此它需要字符串/缓冲区并在您写入时抛出错误。

尝试只做其中一个管道,它会起作用。

编辑

那是我调试错误的方法,一个管道不会导致错误。首先,我们将检查如下所示的数据流:

string stream -> object stream -> string stream
             string          object

您在 MsgExtractStream 中获得的块是来自 inPage 的字符串。任何对象都可以,而不仅仅是字符串。在转换中,您将包裹在对象中的块写入输出。你得到一个字符串并写一个对象。

你现在有两个选择。要解决这个问题,要么MsgExtractStream应该返回字符串,就像你做的那样this.push(chunk),以便下一个管道工作。

或者,如果您需要对象流,您可以从MsgExtractStream. 您将需要另一个这样的管道:

string stream -> object stream -> object stream -> string stream
            string           object           string

第一个对象流从字符串创建对象,第二个对象流从对象创建字符串。您将必须处理沿链的对象类型,以便它通过管道传输。

于 2013-07-25T06:04:21.943 回答