2011-08-31 58 views
1

我在函数中有一个NodeJS readstream监听器,我试图让我的函数返回从监听器内派生的值(文件内容)。返回从NodeJS监听器派生的值

例如:

 
MyObj.prototype.read = function(){ 

    var file3 = fs.createReadStream('test.txt', {encoding: 'utf8'});    
    var contentRead = '';  

    file3.addListener('data', function(data) { 
     contentRead += data.toString('utf-8');  
     return contentRead;    
    }); 
} 

我想这样做VAR内容= myDerivedObj.read()返回文件的内容。

但是,从监听器内部返回的信息没有得到正确的返回 - 得到'undefined'。而且,从监听器外部返回只是返回一个空字符串。

我无法更改read()的签名,所以我无法将回调添加为参数。

回答

2

一般来说,这是一个糟糕的模式:当你做这样的事情时,NodeJS真的很不真实,因为你阻塞了主线程。你会发现你的表现真的很糟糕。所以不要这样做。但如果你必须那么你可以试试这个:

MyObj.prototype.read = function(){ 

    var file3 = fs.createReadStream('test.txt', {encoding: 'utf8'});    
    var contentRead = '';  
    var done = false; 

    file3.addListener('data', function(data) { 
     contentRead += data.toString('utf-8');  
    }); 

    file3.addListener("end", function() { 
     done = true; 
    }); 

    while(!done); 
    return contentRead; 
} 

编辑:@Brandon是正确的,我错了。我只是测试了这一点,尽管我认为回调会起作用,整个节点进程都会锁定。这样做:

MyObj.prototype.read = function(){  
     return fs.readFileSync('test.txt', 'utf-8'); 
    } 
+1

所以,不使用回调和修改方法签名,这样的情况下,什么样的首选模式? – Bamerza

+2

+1。 Node的全部内容都是异步I/O,编写这样的代码与其哲学完全相反。节点有几个同步读取数据的文件系统方法(例如'readFileSync'),主要用于在程序启动时读取小型配置文件,其中不需要异步I/O。否则,你应该尝试接受Node的异步模型(或者使用另一种更合适的技术)。 –

+2

@Bamerza Femi可能有其他想法,但在Node中,您所有的代码(您亲自编写的代码)在单个线程中执行。因此,如果没有回调,你不能*处理I/O和其他异步调用,并且如果使用阻塞调用,Node.js应用将完全锁定,直到从磁盘读取整个文件为止。也就是说,如果你*绝对必须*那么费米提供的代码就可以工作;另外,正如我所提到的,Node提供了它的文件系统方法的[同步版本](http://nodejs.org/docs/v0.4.11/api/fs.html#fs.readFileSync),所以你可以读取文件并把它返还。 –