从JavaScript对象创建Node.js可读流—;最简单的方法
有人能解释一下为什么我在使用节点v0.10.21运行以下代码后出现错误吗 我知道我可以使用JSON.stringify()来处理该对象,以获得大致相同的结果,这里的要点是在objectMode设置为true时理解stream.Readable 错误:从JavaScript对象创建Node.js可读流—;最简单的方法,javascript,node.js,stream,Javascript,Node.js,Stream,有人能解释一下为什么我在使用节点v0.10.21运行以下代码后出现错误吗 我知道我可以使用JSON.stringify()来处理该对象,以获得大致相同的结果,这里的要点是在objectMode设置为true时理解stream.Readable 错误: net.js:612 throw new TypeError('invalid data'); ^ TypeError: invalid data at WriteStream.Socket.write (net
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);
代码:
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流,但进程。stdout
不是,因此它希望有缓冲区
实例写入其中。因为它获取了错误的数据类型,所以抛出了一个错误
如果您希望能够像这样通过管道传输对象,那么需要有一个中间流,它支持作为对象写入和作为缓冲区读取
大概是这样的:
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所指出的,
rs
处于objectMode
,而process.stdout
不是。因此,它希望将缓冲区
s/字符串
s写入它,并在获得对象时抛出类型错误
我们需要将对象流转换为文本,这就是我们要做的:
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));
不管怎么说,我还在把那个东西串起来,对吗?有没有办法把这个东西扔到目的地,让这个家伙做一个字符串?@n370我不太明白。如果您只返回rs
,就会得到这样的结果。您不能直接将rs
管道传输到需要字符串的流。你当然可以把它留给目标流来接受一个对象。哦,我明白了!所以在我们这里的例子中,我们可以让process.stdout
在输出到stdout
之前期望一个对象将其转换为字符串吗?我们可以使用纯节点和JS吗?非常感谢您对@loganfsmythno的关注。不幸的是,这就是为什么您需要像StringifyStream
这样的中间层。您可以编写流来支持这两种功能,但实际情况是这实际上取决于您的用例。有些人可能同样希望编码为XML,因此让stdout
知道这一点是没有意义的。对于其他读者:在另一个关于类似上下文的问题中写下答案。链接:()