If node.js is single-threaded, then why server.listen () returns?

I am familiar with event-based systems in C ++, as well as with java. I tried to find out node.js and came up with interesting behavior, and I was hoping that someone could explain what was going on under the hood.

I have a program that looks like

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); //Why is this not blocking console.log('Main completed'); //main loop here prevents other stuff from working } main(); 

In languages ​​like java or c, I would expect two things. Or server.listen provides an event loop that causes server.listen to never return. Or server.listen creates a new thread and starts the event loop in the new thread, which returns immediately. Then it will call console.log, and then come back and close the program.

To test this, I also added a busy loop under the console .log that looks like.

 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); //Why is this not blocking console.log('Main completed'); while(true){ console.log('hi'); } } main(); 

Server.listen returns immediately, and then loops into the busy cycle as expected. My browser cannot connect to the server, which is expected.

If I delete the busy cycle and return to the source code after console.log ("Main completed"); executed instead of starting the program, the main thread returns to the event loop.

How it works. Why does the main thread return to server code after the main thread returns?

Edit: I think re is allowed that the event queue does not exist in the main function, but where is it? What do they need it for? and when does the main function start with reference to it?

+5
source share
3 answers

Think of http.createServer(handler) and server.listen(port) being similar to someElement.addEventListener('click', handler) in the browser.

When you run someElement.addEventListener('click', handler) , it binds an event listener that will send the handler to the callback queue when the click event someElement on someElement .

http.createServer(handler) combined with server.listen(port) work in a very similar way. http.createServer(handler) returns eventEmitter , and server.listen(port) tells node.js that when an http request is received on this port, this event should be fired. Thus, when the request arrives, the event is fired, and the handler is placed in the callback queue.

At this point, it's just a matter of how the call queue and the callback queue interact. callstack is the current executable stack of functions, the callback queue is the set of callbacks waiting to be executed, and the event loop is what pulls the callbacks out of the callback queue and sends them to the callstack .

So, in a sense, the event loop is what does everything that happens, however, if you block the stop code from emptying, having a synchronous endless loop in one of your callbacks, the event loop never starts again, and callbacks are never executed resulting in a broken / unresponsive application.

+5
source

The fundamental concept for understanding here is the cycle of events and the cooperative (non-preventive) multitasking model .

This server.listen call registers a callback with an event loop below it and this callback server.listen main thread of execution with any other registered callback.

When you throw away this busy loop, the server.listen never gets the runtime (and not a single event mechanism, for that matter), because the system is not proactive. That is, no callback can interrupt any other - callbacks must give up control back in the event loop by ending, after which the event loop will call other registered callbacks based on the events that it has queued.

+1
source

Basically, http.createServer returns a pointer to an EventEmitter . You can join listeners, etc. To the object that will be executed when the event is emitted. They are processed inside an event loop that runs asynchronously and does not block the main thread. Check out the HTTP documentation for more information on HTTP and EventEmitters .

0
source

Source: https://habr.com/ru/post/1235145/


All Articles