2011-08-06 54 views
2

我有一段應用程序有時從文件讀取輸入,有時通過套接字讀取輸入,有時從相同程序的另一部分讀取輸入,以產生緩衝區或字符串。如何正確實現nodejs Stream API?

作爲數據源的套接字和文件都可以使用節點的Stream API來處理,而且我一直試圖想出一些用於緩衝區和字符串的封裝來模仿它;我不想爲了處理字符串作爲輸入而編寫'consumer'代碼的兩個版本,並且當數據已經存在內存中時,我不希望將其寫入磁盤並再次讀取它。

大多數事情似乎工作得很好,但事情是打破我的實現「管」的:

MemoryStream.prototype = new process.EventEmitter; 

MemoryStream.prototype.pipe = function(dest,opts){ 
    var that=this; 
    function pipe_mem(data){ 
     if(!dest.write(data)){ 
      that.pause(); 
      dest.once('drain',function(){ 
       if(pipe_mem(data)){that.resume();} 
      }); 
      return false; 
     } 
     return true; 
    } 
    this.on('data',pipe_mem); 
    if(!opts || opts.end){this.on('end',dest.end);} 
    this.resume(); 
}; 

MemoryStream.prototype.resume = function(){ 
    var i,l,encoder; 
    if(this.active) return; 
    this.active = true; 
    l = this.buffer.length-1; 
    if(l>=0){ 
     encoder = this.encoding?emit_string:emit_buffer; 
     for(i=0;i<l;i++){encoder(this,this.buffer[i],this.encoding);} 
     if(this.buffer[i]===''){ 
      this.emit('end'); 
      this.destroy(); 
     }else{encoder(this,this.buffer[i],encoding);} 
     this.buffer = []; 
    } 
}; 

每當我稱之爲「管」,我得到這個奇怪的錯誤:

TypeError: Object #<EventEmitter> has no method '_implicitHeader' 
    at EventEmitter.<anonymous> (http.js:651:10) 
    at EventEmitter.emit (events.js:61:17) 
    at EventEmitter.resume (/MemoryStream.js:36:9) 

Where /MemoryStream.js行36是this.emit('end');

任何想法是怎麼回事?我該如何解決這個問題,或者,有沒有更好的方法來做我想做的事情?

回答

4

答案是:地方調用是這樣的:

var end = response.end; response.end = function() { end() } 

,而不是像這樣:

var end = response.end; response.end = function() { response.end = end; response.end() } 

你明白嗎? 上下文不同:在第一種情況下,您使用'this === global'調用它,但沒有global._implicitHeader函數,在第二種情況下,您使用'this === response'調用它,並且在那裏是response._implicitHeader函數。

+0

Woa。 JavaScript有一些嚴重的魔力。 – Almo