Reputation: 926
I have been going throug node JS training on newboston channel (link https://www.youtube.com/watch?v=KsjrN-T3ZCs). and Example was given on how Node provides better performance is shown below
function placeAnOrder(orderNumber) {
console.log("Order placed", orderNumber);
cookAndDeliver(function () {
console.log("Delivered order", orderNumber);
});
};
function cookAndDeliver(callback){
setTimeout(callback, 5000);
};
placeAnOrder(1);
placeAnOrder(11);
placeAnOrder(111);
placeAnOrder(1111);
placeAnOrder(11111);
Should you run the sample, you will notice that first all order placed at once, which is normal, and then all of the orders are also delivered once, which is not normal since there is already a timeout constraint of 5 seconds applied per call.
The explanation given by the video was that the call back is none-obstructive and the code will execute unintrrupted, which I concur with, what I don't get is why the node did not honor the timeout value?
My guess is that since it operates in an asynchronous mode then it means that a separate thread is going to handle each call, is my assumption correct?
Upvotes: 0
Views: 137
Reputation: 707328
Here's the sequence of events:
placeAnOrder()
cookAndDeliver()
setTimeout()
setTimeout()
schedules a timer event for 5 seconds from now and returns immediately.placeAnOrder()
cookAndDeliver()
setTimeout()
setTimeout()
schedules a timer event for 5 seconds from now and returns immediately.placeAnOrder()
cookAndDeliver()
setTimeout()
setTimeout()
schedules a timer event for 5 seconds from now and returns immediately.There are no Javascript threads here. Javascript in node.js is single threaded. Everything runs through a central event queue. There may be internals to Javascript that use threads in order to carry out asynchronous operations (for example, async file I/O does use threads internal to its implementation, but not for running the Javascript). When those threads are done, they place an event into the event queue and when the single node.js Javascript thread is done executing what it was doing, it then grabs the next event from the event queue and executes the callback associated with it.
My guess is that since it operates in an asynchronous mode then it means that a separate thread is going to handle each call, is my assumption correct?
No, that is not correct. setTimeout()
schedules a timer event for some future time. There is no Javascript thread associated with a timer event. There may or may not be a single system thread that manages all timer events (that is implementation specific and doesn't really matter - It could also be that whenever Javascript gets back to the event loop, it just checks to see if its time to fire the next timer event). When the time arrives for the timer to fire, an event is inserted into the Javascript event queue. The JS interpreter then picks up that event from the event loop, the next time it's done processing and is looking for the next event to process.
An example was given on how Node provides better performance is shown below
I think what they were trying to show is that because of the node.js asynchronous event-driven design, there are NOT multiple threads for asynchronous events like timers. That allows it to scale better when there are lots of asynchronous operations in flight at the same time because its model is more efficient than a model where there is a system thread for every timer.
Should you run the sample, you will notice that first all order placed at once, which is normal, and then all of the orders are also delivered once, which is not normal since there is already a timeout constraint of 5 seconds applied per call.
The code essentially runs 5 setTimeout()
calls in a row that all set a timer to fire 5 seconds from now. setTimeout()
is non-blocking. That means it schedules the timer for 5 seconds from now and then IMMEDIATELY goes on to the next line of code which also schedules a timer for 5 seconds from now. So you end up with 5 timers all scheduled for about 5 seconds from now (perhaps varying only be a few ms of execution time from one setTimeout()
call to the next. The end result is that all 5 timers will fire in about 5 seconds and they will fire in the order they were scheduled.
The explanation given by the video was that the call back is none-obstructive and the code will execute unintrrupted, which I concur with, what I don't get is why the node did not honor the timeout value?
Because setTimeout()
is non-blocking (as are all asynchronous operations in node.js). It schedules the timer for some future time and then immediately returns (that's the non-blocking part). It does not wait 5 seconds to return. It returns immediately and executes whatever code comes next. Then 5 seconds from now (when the JS interpreter has nothing else to do), the timer callback will get called.
Upvotes: 3
Reputation: 2750
It does honor the timeout. The timeout is for the callback, and not the execution of the function. So what happened is that all of your function calls executed asynchronously, and they all waited five seconds, and they all returned. So they all took five seconds between starting and finishing. Node doesn't have to wait for the first function to complete before the second one to complete.
Basically for a non-trivial example i.e. waiting on a db call. you don't have to wait for one db call to finish before sending a second db call. And if the db is threaded, you can get the results pretty much at the same time.
Upvotes: 1