我有一个应用程序,它有时从文件中读取输入,有时从套接字中读取输入,有时从同一程序的另一部分读取输入,该部分产生缓冲区或字符串。
套接字和文件作为数据源都可以用节点的流API处理,我一直在尝试为缓冲区和字符串提供某种包装器来模拟;我不想写两个版本的"消费者"代码只是为了处理字符串作为输入,当数据已经在内存中,我不想把它写到磁盘上,然后再读回来。
大多数事情似乎工作得很好,但是有些东西破坏了我的'pipe'的实现:
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 = [];
}
};
当我调用'pipe'时,我得到这个奇怪的错误:
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');
知道是怎么回事吗?我该如何解决这个问题,或者,有没有更好的方法来做我想做的事?
答案是:在某个地方你调用像这样的东西:
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函数。