简体   繁体   English

node.js事件队列在哪里?

[英]Where is the node.js event queue?

I have seen similar questions on stack overflow but none of them fully dive down into the question that I have? 我已经看到类似的堆栈溢出问题,但没有一个完全深入到我的问题? I am familiar with event queues, how they work as well as implementing them. 我熟悉事件队列,它们如何工作以及实现它们。 I am new to node.js and I am trying to wrap my head around how Node.js does it. 我是node.js的新手,我试图围绕Node.js如何做到这一点。

In a c++ application you would do something along the lines of: 在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);
         }
     }
}

Now in the case of node.js I might have a main file called main.js that looks like. 现在在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();

I understand the server.listen is attaching a handler to the event queue and that we are adding the callback similar to the c++ example. 我理解server.listen正在将一个处理程序附加到事件队列,并且我们正在添加类似于c ++示例的回调。

My question is. 我的问题是。 Where is the event queue? 事件队列在哪里? Is it in the javascript somewhere or is it built into the interpreter? 它是在某个地方的javascript中还是内置于解释器中? Also how does the main function get called relative to the main event loop? 另外,如何相对主事件循环调用main函数?

Where is the event queue? 事件队列在哪里? Is it in the javascript somewhere or is it built into the interpreter? 它是在某个地方的javascript中还是内置于解释器中?

The event queue is built into the operating environment that hosts the Javascript interpreter. 事件队列内置于托管Javascript解释器的操作环境中。 It isn't fundamental to Javascript itself so it's not part of the actual JS runtime. 它不是Javascript本身的基础,因此它不是实际JS运行时的一部分。 One interesting indicator of this is that setTimeout() is not actually part of ECMAScript, but rather something made available to the Javascript environment by the host. 一个有趣的指标是setTimeout()实际上不是ECMAScript的一部分,而是主机为Javascript环境提供的东西。

The system surrounding the Javascript implementation in node.js keeps track of externally triggered events (timers, networking results, etc...) and when Javascript is not busy executing something and an external event occurs, it then triggers an associated Javascript callback. 围绕node.js中的Javascript实现的系统跟踪外部触发的事件(定时器,网络结果等等),当Javascript不忙于执行某事并发生外部事件时,它会触发相关的Javascript回调。 If Javascript is busy executing something, then it queues that event so that as soon as Javascript is no longer busy, it can then trigger the next event in the queue. 如果Javascript忙于执行某些操作,那么它会对该事件进行排队,这样一旦Javascript不再忙,它就可以触发队列中的下一个事件。

node.js itself uses libuv for the event loop. node.js本身使用libuv作为事件循环。 You can read more about that here . 你可以在这里阅读更多相关信息。 It provides a multi-platform way of doing evented, async I/O that was developed for node.js, but is also being used by some other projects. 它提供了一种多平台方式来执行为node.js开发的事件异步I / O,但也被其他一些项目使用。

Here's a related answer that might also help: 这是一个相关的答案,也可能有所帮助:

Run Arbitrary Code While Waiting For Callback in Node? 在节点中等待回调时运行任意代码?

Also how does the main function get called relative to the main event loop? 另外,如何相对主事件循环调用main函数?

When node.js starts up, it is given an initial script file to execute. 当node.js启动时,会给它一个要执行的初始脚本文件。 It loads that script file into memory, parses the Javascript in it and executes it. 它将该脚本文件加载到内存中,解析其中的Javascript并执行它。 In your particular example, that will cause the function main to get parsed and then will cause the execution of main() which will run that function. 在您的特定示例中,这将导致函数main被解析,然后将导致执行将运行该函数的main()

Loading, parsing and executing the script file passed to node when it starts up is the task given to node.js. 加载,解析和执行启动时传递给节点的脚本文件是给node.js的任务。 It isn't really related to the event queue at all. 它根本与事件队列无关。 In some node.js applications, it runs that initial script and then exits (done with its work). 在某些node.js应用程序中,它运行该初始脚本然后退出(完成其工作)。 In other node.js applications, the initial script starts timers or servers or something like that which will receive events in the future. 在其他node.js应用程序中,初始脚本启动计时器或服务器或将来会接收事件的计时器。 When that is the case, node.js runs the initial script to completion, but because there are now lasting objects that were created and are listening for events (in your case, a server), nodejs does not shut down the app. 在这种情况下,node.js将初始脚本运行完成,但由于现在有持久对象已创建并正在侦听事件(在您的情况下是服务器),因此nodejs不会关闭应用程序。 It leaves it running so that it can receive these future events when they occur. 它使它保持运行,以便它们在发生时可以接收这些未来事件。


One missing piece here is that things like the server object you created allow you to register a callback that will be called one or more times in the future when some particular events occur. 这里缺少的一件事是你创建的服务器对象之类的东西允许你注册一个回调,当某些特定事件发生时,将在未来调用一次或多次。 This behavior is not built into Javascript. 此行为不是内置于Javascript中。 Instead, the code that implements these objects or the TCP functions that they use must maintain a list of callbacks that are registered and when those events occur, it must execute code so that the appropriate callbacks are called and passed the appropriate data. 相反,实现这些对象的代码或它们使用的TCP函数必须维护一个已注册的回调列表,当这些事件发生时,它必须执行代码,以便调用适当的回调并传递适当的数据。 In the case of http.createServer() , it is a mix of Javascript and native code in the nodejs http library that make that work. http.createServer()的情况下,它是nodejs http库中的Javascript和本机代码的混合,使其工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM