【问题标题】:Returning a value derived from a NodeJS listener返回从 NodeJS 侦听器派生的值
【发布时间】:2011-08-31 00:25:15
【问题描述】:

我在一个函数中有一个 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'); 返回内容读取; }); }

我想做类似 var contents = myDerivedObj.read() 的操作来返回文件的内容。

但是,来自侦听器内部的返回没有正确返回 - 得到“未定义”。而且,从侦听器外部返回只会返回一个空字符串。

我无法更改 read() 的签名,因此无法添加回调作为参数。

【问题讨论】:

    标签: javascript node.js closures


    【解决方案1】:

    一般来说,这是一个糟糕的模式:当你做这样的事情时,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。 Node 的重点是异步 I/O,编写这样的阻塞代码与其理念完全背道而驰。 Node有一些同步读取数据的文件系统方法(例如readFileSync),主要用于在程序启动期间读取不需要异步I/O的小型配置文件。否则,您应该真正尝试采用 Node 的异步模型(或使用另一种更合适的技术)。
    • @Bamerza Femi 可能有其他想法,但在 Node 中,您自己的所有代码(您个人编写的代码)都在单个线程中执行。因此,如果没有回调,您无法处理 I/O 和其他异步调用,并且您的 Node.js 应用程序将完全锁定直到从磁盘读取整个文件如果您使用阻塞呼叫。也就是说,如果您绝对必须,那么 Femi 提供的代码将起作用;此外,正如我所提到的,Node 提供了其文件系统方法的synchronous versions,因此您可以读取文件并返回它。
    • @Brandon:创建一个答案,我会删除我的。
    猜你喜欢
    • 2012-11-05
    • 2021-04-22
    • 2013-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多