node.js事件队列在哪里?

时间:2015-11-04 00:53:16

标签: javascript c++ node.js

我已经看到类似的堆栈溢出问题但是没有一个完全深入到我的问题中?我熟悉事件队列,它们如何工作以及实现它们。我是node.js的新手,我正试图了解Node.js是如何做到的。

在c ++应用程序中,您可以执行以下操作:

int main(){
    std::vector<Handler*> handlers;
    BlockingQueue queue = new BlockingQueue();
    //Add all the handlers call constructors and other such initialization

    //Then run the event loop
    while(true){
        Event e = queue.pop();

        for( std::vector<Handler>::iterator it = handlers.begin(); it != handlers.end(); ++it){
            *it.handle(e);
         }
     }
}

现在在node.js的情况下,我可能有一个名为main.js的主文件,看起来像。

var http = require("http");
function main(){
    // Console will print the message
    console.log('Server running at http://127.0.0.1:8080/');
    var server = http.createServer(function (request, response) {

        // Send the HTTP header
        // HTTP Status: 200 : OK
        // Content Type: text/plain
        response.writeHead(200, {'Content-Type': 'text/plain'});

        // Send the response body as "Hello World"
        response.end('Hello World\n');
    });

    server.listen(8080);
    console.log('Main completed');
}

main();

我理解server.listen正在将一个处理程序附加到事件队列,并且我们正在添加类似于c ++示例的回调。

我的问题是。事件队列在哪里?它是在某个地方的javascript中还是内置于解释器中?另外,如何相对于主事件循环调用main函数?

1 个答案:

答案 0 :(得分:4)

  

事件队列在哪里?是在某个地方的javascript或是它   内置于翻译中?

事件队列内置于托管Javascript解释器的操作环境中。它不是Javascript本身的基础,因此它不是实际JS运行时的一部分。一个有趣的指标是setTimeout()实际上并不是ECMAScript的一部分,而是由主机提供给Javascript环境的东西。

在node.js中围绕Javascript实现的系统跟踪外部触发的事件(定时器,网络结果等等),当Javascript不忙于执行某事并发生外部事件时,它会触发相关的Javascript打回来。如果Javascript忙于执行某些操作,那么它会对该事件进行排队,这样一旦Javascript不再忙,它就可以触发队列中的下一个事件。

node.js本身使用libuv作为事件循环。您可以阅读有关here的更多信息。它提供了一种多平台方式来执行为node.js开发的事件异步I / O,但也被其他一些项目使用。

这里有一个相关的答案,可能也有帮助:

Run Arbitrary Code While Waiting For Callback in Node?

  

此外,main函数是如何相对于主事件调用的   循环?

当node.js启动时,会给它一个要执行的初始脚本文件。它将该脚本文件加载到内存中,解析其中的Javascript并执行它。在您的特定示例中,这将导致函数main被解析,然后将导致执行将运行该函数的main()

加载,解析和执行启动时传递给节点的脚本文件是给node.js的任务。它根本不与事件队列有关。在某些node.js应用程序中,它运行该初始脚本然后退出(完成其工作)。在其他node.js应用程序中,初始脚本启动计时器或服务器或将来会接收事件的计时器。在这种情况下,node.js将初始脚本运行完成,但由于现在有持久对象已创建并正在侦听事件(在您的情况下是服务器),因此nodejs不会关闭应用程序。它使它保持运行,以便它们在发生时可以接收这些未来事件。

这里缺少的一件事是,您创建的服务器对象之类的内容允许您注册将在某些特定事件发生时将被调用一次或多次的回调。此行为不是内置于Javascript中。相反,实现这些对象的代码或它们使用的TCP函数必须维护一个已注册的回调列表,当这些事件发生时,它必须执行代码,以便调用适当的回调并传递适当的数据。在http.createServer()的情况下,它是nodejs http库中Javascript和本机代码的混合,可以使其工作。