Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why does the setTimeout not get called when invoked from inside an infinite while loop

I bumped into a funny problem, I was trying to invoke a function (which has a setTimeout in its body) from an infite loop, and it was never getting called, but when the loop is changed into not infite the call was happening!!

this works :-

var bar = function() {
    setTimeout(function() {
        console.log("1");
    }, 0);
};

var count = 4;
while(count > 0){
  bar();
  count --;
}

this never works . : -

var bar = function() {
  setTimeout(function() {
    console.log("1");
  }, 1000);
};

while (true) {
  bar();
}

can anybody explain whats going on in here! how to call a function with a setTimeout in its body from an infinite loop?

like image 731
isnvi23h4 Avatar asked Dec 06 '25 23:12

isnvi23h4


2 Answers

This is because of the way the event loop works. Async events like timeouts are queued up and are processed after the main body of your script runs-to-completion. This means it is waiting for your while loop to finish before it evens starts looking at the setTimeout callbacks. This is one (of several) reasons why you don't want to block the thread with long-running synchronous code like giant loops in javascript. Nothing else can happen while your infinite while loop is spinning.

like image 61
Mark Avatar answered Dec 08 '25 14:12

Mark


Let's see first how this (infinite) code executes

CURRENT EXECUTION                               WAITING FOR EXECUTION (IN QUEUE)
===================                             ================================

=> variable bar is assigned to a function
=> while (true)
=> call bar()
=> inside bar()
=> setTimeout function will be sent to queue    => Execute setTimeout’s function after 1000ms(1)
=> while (true)                         
=> call bar()                           
=> inside bar()                         
=> setTimeout function will be sent to queue    => Execute setTimeout’s function after 1000ms(2)
=> call bar()                           
=> inside bar()                         
=> setTimeout function will be sent to queue    => Execute setTimeout’s function after 1000ms(3)
.
.
. while (true) => happens forever           => waits forever…

If you want to call a function with a setTimeout inside an infinite loop, then you can use something like this,

var bar = function() {
    setTimeout(function() {
        console.log("1");
        runBar();
   }, 1000);
};

function runBar() {
    bar();
}
runBar();
like image 30
Kapil Dev S Avatar answered Dec 08 '25 13:12

Kapil Dev S