2014-01-14 59 views
9

任何人都可以解釋爲什麼我運行以下代碼與節點v0.10.21後得到一個錯誤?從JavaScript對象創建一個Node.js可讀流 - 最簡單的方法

我知道我可以JSON.stringify()該對象爲了實現或多或少相同的結果,這裏的重點是使stream.Readable當objectMode設置爲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); 
+0

進一步的讀者:在一個問題寫了一封關於類似情況下的答案。鏈接:(http://stackoverflow.com/a/35886734/1453339) – johnshumon

回答

17

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); 
+0

無論如何,我仍然stringifing該對象的權利?有沒有什麼方法可以將對象轉儲到目的地,讓這個人把它變成一個字符串? – n370

+0

@ n370不知道我關注。如果你只是返回'rs',那就是你得到的。你不能直接將'rs'管道傳輸到期望字符串的流。你當然可以把它留給目標流來接受一個對象。 – loganfsmyth

+0

哦,我明白了!所以在我們這裏的情況下,我們可以讓'process.stdout'在輸出到'stdout'之前期望一個對象將它變成一個字符串嗎?我們可以使用純節點和JS嗎?我非常感謝你的關注@loganfsmyth – n370

3

由於loganfsmyth指出,rsobjectMode,而process.stdout不是。所以它預計會有Buffer s/String寫到它,並且當它得到Object時拋出TypeError

我們需要的對象的流轉換爲文本,這是什麼JSONStream由做:

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

我是誰不知道很多關於節點的人(我只是需要有我咕嘟咕嘟設置工作)。因此,我需要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)); 
相關問題