从 JavaScript 对象创建 Node.js 可读流 — 最简单的方法



谁能解释为什么我在节点 v0.10.21 运行以下代码后出现错误?

我知道我可以 JSON.stringify() 该对象以获得或多或少相同的结果,这里的重点是理解流。当对象模式设置为 true 时可读。

错误:

net.js:612
    throw new TypeError('invalid data');
          ^
TypeError: invalid data
    at WriteStream.Socket.write (net.js:612:11)
    at write (_stream_readable.js:583:24)
    at flow (_stream_readable.js:592:7)
    at _stream_readable.js:560:7
    at process._tickCallback (node.js:415:13)
    at Function.Module.runMain (module.js:499:11)
    at startup (node.js:119:16)
    at node.js:901:3

代码:

var stream = require('stream');
var edad = require(__dirname + '/public/edad.json');
var rs = new stream.Readable({ objectMode: true });
rs.push(edad);
rs.push(null);
rs.pipe(process.stdout);

rs 是一个 objectMode 流,但process.stdout不是,所以它期望将Buffer实例写入其中。由于它获取了错误的数据类型,因此会引发错误。

如果希望能够像这样通过管道传输对象,则需要有一个中间流,该流支持作为对象写入和作为缓冲区读取。

像这样:

var stream = require('stream');
var util = require('util');
function StringifyStream(){
    stream.Transform.call(this);
    this._readableState.objectMode = false;
    this._writableState.objectMode = true;
}
util.inherits(StringifyStream, stream.Transform);
StringifyStream.prototype._transform = function(obj, encoding, cb){
    this.push(JSON.stringify(obj));
    cb();
};

var edad = require(__dirname + '/public/edad.json');
var rs = new stream.Readable({ objectMode: true });
rs.push(edad);
rs.push(null);
rs.pipe(new StringifyStream()).pipe(process.stdout);

正如 loganfsmyth 所指出的,rsobjectMode 中,而process.stdout不是。因此,它期望将Buffer s/String写入其中,并在获得Object时抛出TypeError

我们需要将对象流转换为文本,这就是 JSONStream 的作用:

JSONStream = require('JSONStream');
rs.pipe(JSONStream.stringify()).pipe(process.stdout);

我是一个对 Node 了解不多的人(我只需要让我的 Gulp 设置正常工作)。正因为如此,我需要 20+ 行代码和像 stream.push(null) 这样的奇怪调用来处理流中的变量这一事实似乎有点疯狂。

这对我有用:

var data = { "prop1": "val1", "prop2": "val2" };
var dest = 'path/to/dest/config.json';
var s = require('stream');
var stream = new s.Readable();
stream.push(JSON.stringify(data));    // stream apparently does not accept objects
stream.push(null);                    // no idea why this is needed, but it is
return stream
    .pipe()                           // whatever you need
    .pipe($.fs.createWriteStream(dest));

相关内容

  • 没有找到相关文章

最新更新