node.js中的高效闭包结构

时间:2013-09-24 16:13:54

标签: javascript node.js

我开始在node.js中编写一个服务器,并想知道我是否正确地做事......

基本上我的结构类似于以下伪代码:

function processStatus(file, data, status) {
...
}

function gotDBInfo(dbInfo) {
    var myFile = dbInfo.file;
    function gotFileInfo(fileInfo) {
        var contents = fileInfo.contents;
        function sentMessage(status) {
            processStatus(myFile, contents, status);
        }
        sendMessage(myFile.name + contents, sentMessage);
    }
    checkFile(myFile, gotFileInfo);
}
checkDB(query, gotDBInfo);

一般来说,我想知道这是否是编写node.js的正确方法,更具体地说:

1)VM是否足够智能,可以在每次回调之间“同时”(即切换上下文)运行,而不会被大量连接的客户端挂起?

2)当运行垃圾收集时,如果最后一个回调(processStatus)完成,它会完全清除内存吗?

1 个答案:

答案 0 :(得分:2)

  1. Node.js基于事件,所有代码基本上都是事件处理程序。 V8引擎将执行处理程序中的任何同步代码,然后处理下一个事件。

    异步调用(网络/文件IO)会将事件发布到另一个线程来执行阻塞IO(即 libev libeio AFAIK,我可能错了这个)。您的应用程序可以处理其他客户端。 IO任务完成后,将触发一个事件并调用您的回调函数。

    以下是异步调用流程的示例,模拟处理客户端请求的Node应用程序:

    onRequest(req, res) {
        // we have to do some IO and CPU intensive task before responding the client
    
        asyncCall(function callback1() {
            // callback1() trigger after asyncCall() done it's part
            // *note that some other code might have been executed in between*
    
            moreAsyncCall(function callback2(data) {
                // callback2() trigger after moreAsyncCall() done it's part
                // note that some other code might have been executed in between
    
                // res is in scope thanks to closure
                res.end(data);
    
                // callback2() returns here, Node can execute other code
                // the client should receive a response
                // the TCP connection may be kept alive though
            });
    
            // callback1() returns here, Node can execute other code
            // we could have done the processing of asyncCall() synchronously 
            // in callback1(), but that would block for too long 
            // so we used moreAsyncCall() to *yield to other code*
            // this is kind of like cooperative scheduling
        });
    
        // tasks are scheduled by calling asyncCall()
        // onRequest() returns here, Node can execute other code
    }
    
  2. 当V8没有足够的内存时,它会进行垃圾回收。它知道实时JavaScript对象是否可以访问一块内存。我不确定它是否会在达到功能结束后积极清理内存。

  3. 参考文献:

    This Google I/O演讲讨论了Chrome的GC机制(因此是V8)。

    http://platformjs.wordpress.com/2010/11/24/node-js-under-the-hood/

    http://blog.zenika.com/index.php?post/2011/04/10/NodeJS