Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Strange behaviour in JavaScript for loops

I have a piece of code which blocks the event loop and waits of N milliseconds:

function sleep(milliseconds) {
    var start = new Date().getTime()
    console.log(`start: ${start}`)
    for (var i = 0; i < 1e7; i++) {
        const delta = new Date().getTime() - start
        console.log(`milliseconds passed: ${delta}`)
        if (delta > milliseconds) {
            console.log('exiting')
            console.log(`final delta: ${delta}`)
            break
        }
    }
}

sleep(5000)
console.log('the end')

When I run it (in browser or Node) I get the expected result:
‘start’ output, bunch of ‘milliseconds passed’, and then N milliseconds later I get ‘exiting’ and ‘the end’. No problem here.

But when I comment out console.log(`milliseconds passed: ${delta}`) in the body of the for loop:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

function sleep(milliseconds) {
    const start = new Date().getTime()
    console.log(`start: ${start}`)
    for (var i = 0; i < 1e7; i++) {
        const delta = new Date().getTime() - start
        // console.log(`milliseconds passed: ${delta}`)
        if (delta > milliseconds) {
            console.log('exiting')
            console.log(`final delta: ${delta}`)
            break
        }
    }
}

sleep(5000)
console.log('the end')

I get totally surprising results:
I see ‘start’ output as before, but then it returns immediately and outputs ‘the end’. So it’s like for loop didn’t run at all or stopped running for some reason and program never went into if statement that prints ‘exiting’. The only thing that changed between the two snippets of code is commented out console.log statement, and yet behaviour changed drastically.

Can anyone please explain what is going on here?

>Solution :

The loop ran, it just ran quickly, since the bulk of the time-consuming work it does is the console.log that you’re commenting-out. It doesn’t take a modern JavaScript engine long at all to loop a million times, even if it is creating an object on each iteration (the Date). You can tell if you look for side-effects, like the final value of i (since you’re using var, we can see that value when the loop is over):

function sleep(milliseconds) {
    const start = new Date().getTime();
    console.log(`start: ${start}`);
    for (var i = 0; i < 1e7; i++) {
        const delta = new Date().getTime() - start;
        // console.log(`milliseconds passed: ${delta}`)
        if (delta > milliseconds) {
            console.log("exiting");
            console.log(`final delta: ${delta}`);
            break;
        }
    }
    if (i === 1e7) {
        console.log(`Reached main termination condition after ${Date.now() - start}ms`);
    }
    return i;
}

const result = sleep(5000);
console.log(`The end, result = ${result}`);

On my machine, that loop completes because i reaches 1e7 in just under a second — well before the five seconds are up.

A couple of things worth noting:

  • It’s best practice not to have busy-loops like this in real code. 🙂
  • new Date().getTime() can be replaced with Date.now(), which gives you the same thing without an object allocation. All modern and even many obsolete browsers (such as IE9+) support it.
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading