node.js事件队列在哪里?

node.js事件队列在哪里?

问题描述:

我已经看到类似的堆栈溢出问题,但没有一个完全潜入我的问题?我熟悉事件队列,他们如何工作以及如何实施。我是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的某处,还是内置于解释器?还有,主函数是如何相对于主事件循环调用的?

+0

事件队列是内置的。当事件发生时,它将事件推入调用堆栈,也是内置的。调用堆栈中的调用在当前调用完成之前不会被调用。 – Blindman67

事件队列在哪里?它是在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?

另外请问在主函数被调用相对于主事件 循环?

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

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


一个在这里失踪一块是物像您所创建的服务器对象允许您注册一个回调,当一些特定的事件发生,将被称为未来的一次或多次。这种行为没有内置到Javascript中。相反,实现这些对象或它们使用的TCP函数的代码必须维护已注册的回调列表,并且当这些事件发生时,它必须执行代码,以便调用适当的回调并传递适当的数据。在http.createServer()的情况下,它是Javascript和本地代码在nodejs http库中的组合,它可以实现这一点。

+0

在操作环境中,你是指节点解释器吗?如果是这样的话。在解释器跳入事件处理之前,我的主函数是否被调用,或者它是否作为事件进行调用? – nbroeking

+0

Node.js中的本地事件循环基于libuv构建https://en.wikipedia.org/wiki/Libuv –

+0

@nbroeking - “操作环境”是实际解释器周围的代码集,而不是Javascript解释器本身 - 在这种情况下,解释器是V8引擎,解释器周围的代码是node.js在V8之外添加的。查看我最近添加到其他问题的答案中的其他内容。 – jfriend00