Search code examples
javascriptloopssettimeoutinfinite-loop

Why does using Date.now() in condition create an infinite loop?


I wanted to create a loop that could simulate a 5 second delay but ended up creating an infinite loop. I don't get why that works this way.

let a = Date.now() + 5000;
while(Date.now() < a) {
    console.log(1);
}

What is wrong? a is a fixed value and isn't Date.now() supposed to get changed after every iteration?

I'm also wondering why setTimeout still works when the loop is infnite? Isn't it supposed to get executed only after the currently executing script is complete? Since this script is never complete why does setTimeout still get invoked?

setTimeout(() => {
    alert(2);
}, 2000);
let a = Date.now() + 5000;
while( Date.now() < a ) {
    console.log(1)
}


Solution

  • Actually your code is not creating infinite loop. It will keep printing 1 until 5 seconds over. I tested it locally. But print is pretty fast, it looks like infinite loop. Scroll down and see at the end printing will be stopped. You can try same code by giving just 500 ms.

    let a = Date.now() + 500;
    while(Date.now() < a) {
        console.log(1);
    }
    console.log("finished");

    Now come to another question to understand why setTimeout worked, you have to understand internal working of Javascript. I will recommend this video How JavaScript Works 🔥& Execution Context

    In JS, all functions which will execute are pushed to call stack for execution. In this case console.log method in while loop .

    JS engine also has a callback queue which will have callback functions ready to be executed and there is event loop which always checks if call stack is empty. If yes, it will take the callback function from the callback queue and push it to the call stack for execution. Here setTimeout function has a callback, once timer will expire this callback will be pushed to the callback queue.

    Your while loop is just pushing console.log for execution one after another and it's getting executed in no time. But as soon as there is a callback present in the callback queue and call stack is empty for a moment (means it's ready for another function to execute), event loop just push the callback for execution and removes from the queue. This process will be continued till all callbacks in the queue will be executed. So callbacks have higher priority when it comes to execution. You can try example with multiple setTimeout as well.

    Hope this will help you.