Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does setTimeout work in Node.JS?

People also ask

Can we use setTimeout in node JS?

The setTimeout function is used to call a function after the specified number of milliseconds. The delay of the called function begins after the remaining statements in the script have finished executing. The setTimeout function is found in the Timers module of Node. js.

How does the setTimeout work?

The setTimeout() sets a timer and executes a callback function after the timer expires. In this syntax: cb is a callback function to be executed after the timer expires. delay is the time in milliseconds that the timer should wait before executing the callback function.

Why is the setTimeout () function used?

Note: The setTimeout() method is useful when you want to execute a block of once after some time. For example, showing a message to a user after the specified time.

How does setTimeout return a value?

To get return value from setTimeout with JavaScript, we can create a promise from the setTimeout code. const x = () => { const promise = new Promise((resolve, reject) => { window. setTimeout(() => { resolve("done!"); }); }); return promise; }; const y = async () => { const result = await x(); console. log(result); };


The semantics of setTimeout are roughly the same as in a web browser: the timeout arg is a minimum number of ms to wait before executing, not a guarantee. Furthermore, passing 0, a non-number, or a negative number, will cause it to wait a minimum number of ms. In Node, this is 1ms, but in browsers it can be as much as 50ms.

The reason for this is that there is no preemption of JavaScript by JavaScript. Consider this example:

setTimeout(function () {
  console.log('boo')
}, 100)
var end = Date.now() + 5000
while (Date.now() < end) ;
console.log('imma let you finish but blocking the event loop is the best bug of all TIME')

The flow here is:

  1. schedule the timeout for 100ms.
  2. busywait for 5000ms.
  3. return to the event loop. check for pending timers and execute.

If this was not the case, then you could have one bit of JavaScript "interrupt" another. We'd have to set up mutexes and semaphors and such, to prevent code like this from being extremely hard to reason about:

var a = 100;
setTimeout(function () {
  a = 0;
}, 0);
var b = a; // 100 or 0?

The single-threadedness of Node's JavaScript execution makes it much simpler to work with than most other styles of concurrency. Of course, the trade-off is that it's possible for a badly-behaved part of the program to block the whole thing with an infinite loop.

Is this a better demon to battle than the complexity of preemption? That depends.


The idea of non-blocking is that the loop iterations are quick. So to iterate for each tick should take short enough a time that the setTimeout will be accurate to within reasonable precision (off by maybe <100 ms or so).

In theory though you're right. If I write an application and block the tick, then setTimeouts will be delayed. So to answer you're question, who can assure setTimeouts execute on time? You, by writing non-blocking code, can control the degree of accuracy up to almost any reasonable degree of accuracy.

As long as javascript is "single-threaded" in terms of code execution (excluding web-workers and the like), that will always happen. The single-threaded nature is a huge simplification in most cases, but requires the non-blocking idiom to be successful.

Try this code out either in your browser or in node, and you'll see that there is no guarantee of accuracy, on the contrary, the setTimeout will be very late:

var start = Date.now();

// expecting something close to 500
setTimeout(function(){ console.log(Date.now() - start); }, 500);

// fiddle with the number of iterations depending on how quick your machine is
for(var i=0; i<5000000; ++i){}

Unless the interpreter optimises the loop away (which it doesn't on chrome), you'll get something in the thousands. Remove the loop and you'll see it's 500 on the nose...


setTimeout is a kind of Thread, it holds a operation for a given time and execute.

setTimeout(function,time_in_mills);

in here the first argument should be a function type; as an example if you want to print your name after 3 seconds, your code should be something like below.

setTimeout(function(){console.log('your name')},3000);

Key point to remember is, what ever you want to do by using the setTimeout method, do it inside a function. If you want to call some other method by parsing some parameters, your code should look like below:

setTimeout(function(){yourOtherMethod(parameter);},3000);

The only way to ensure code is executed is to place your setTimeout logic in a different process.

Use the child process module to spawn a new node.js program that does your logic and pass data to that process through some kind of a stream (maybe tcp).

This way even if some long blocking code is running in your main process your child process has already started itself and placed a setTimeout in a new process and a new thread and will thus run when you expect it to.

Further complication are at a hardware level where you have more threads running then processes and thus context switching will cause (very minor) delays from your expected timing. This should be neglible and if it matters you need to seriously consider what your trying to do, why you need such accuracy and what kind of real time alternative hardware is available to do the job instead.

In general using child processes and running multiple node applications as separate processes together with a load balancer or shared data storage (like redis) is important for scaling your code.