Explanation Node Callbacks and Single-Threaded

Is the javascript node environment solitary, or is everything happening at the same time? Or (more likely) none of these statements explain what happens to node.

I am new to node and trying to understand how it handles callbacks. My googling on this issue did not turn out to be fruitful, and it seems that several audiences use terms such as "flows, blocking and single-threaded" with difference contexts for each audience, and I do not have enough experience working with node to correctly parse what I'm reading.

From what I read, the node javascript runtime, like the browser, is single-threaded. That is, despite the fact that everything is developed around asynchronous callbacks, everything happens in a deterministic order, and there are never two threads that change the same variable or run statements at the same time. I also read this that the node user programmer does not have to worry about locking semantics.

If I'm in a browser and use one of the popular javascript libraries to set a callback to a non-dom-event-handler, something like

console.log("Here"); $.each([1,2,3],function(){ console.log("-- inside the callback --"); }); console.log("There"); 

My conclusion is consistent

 Here -- inside the callback -- -- inside the callback -- -- inside the callback -- There 

However, if I do something similar with a callback in node js (by running it as a shell script from the command line)

 var function example() { var fs = require('fs'); console.log("Here"); fs.readdir('/path/to/folder', function(err_read, files){ console.log('-- inside the callback --'); }); console.log("There"); for(var i=0;i<10000;i++) { console.log('.'); } } example(); console.log("Reached Top"); 

I consistently (apparently see "not much experience" above) get these results

 Here There . . (repeat 10,000 times) Reached Top -- inside the callback -- 

That is, node terminates the execution of the example function before calling the callback.

Is this deterministic behavior in node? Or there are times when a callback will be called before the example function completes? Or will it depend on the implementation in the library with a callback?

I understand that the idea of ​​a node is to write event-based code, but I'm trying to figure out what the node really does, and what behavior you can rely on and what not.

+6
source share
3 answers

In this case, you call a function that performs IO and asynchronous. That is why you see the result the way you do.

Since the rest of your code executes inline - in a single thread of execution, it exits before IO events get a chance to break into the event loop.

I would say that I expect this behavior, but not depend on it with absolute certainty, since it depends on the implementation of the library with a callback. A developer (bad, evil) could make a synchronous request to check if there is any work, and if not, a callback immediately. (I hope you never see this, but ...).

+1
source

Is node a javascript environment single, or is everything happening at the same time?

Node has a single-threaded program execution model, which means that only one command will be executed during a single node process. Execution will continue until the program gives control. This can happen at the end of the program code or when the callback reaches the end.

In the first case:

 console.log("Here"); $.each([1,2,3],function(){ console.log("-- inside the callback --"); }); console.log("There"); 

The key is that $.each uses callbacks synchronously, so it effectively calls callbacks in a deterministic order.

Now in the second case, fs.readdir uses callbacks asynchronously - it places a callback in anticipation of the event being fs.readdir (that is, it ends when the directory is read). This can happen anytime. However, the calling function does not give control, so example always ends before any of the calls is called.

In one sentence: All function / global scope code is executed before any callbacks defined in that function / global scope.

+2
source

I would like to add a bit to @ dc5's answer. On it the site they describe node as

Node.js uses an event-driven , non-blocking I / O model

The event driven element is very significant. This usually eliminates my doubts when it is difficult for me to understand the node program execution model.

So, in your example, what happens is:

  • It is printed on the console here.

  • An animated call is made to files.

  • Node attaches the listener to an asynchronous call.

  • Continues the execution line and prints.

Now it may happen that the asynchronous call is completed before the current code fragment is executed, but node js completes the task at hand and then returns to serve the asynchronous call.

Therefore, instead of waiting for something, he continues to work in line. Therefore, the node js run loop never works.

+1
source

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


All Articles