2

I am trying to write a for loop that has a delay between running each iteration. I thought Id go about it by using setTimeout() as follows.

Input:

for (let i=0;i<3;i++){
  setTimeout(()=>{console.log("hi")},10000)
}

Output:

hi
hi
hi

What seems to be happening is that its waiting 10 seconds and then runs the entire for loop, rather than waiting 10 seconds to run each iteration of the for loop. After the first hi is shown to the console, the other 2 follow instantaneously. Why is this the case, rather than a delayed logging of hi and how can I go about doing this?

Vishal Jain
  • 443
  • 4
  • 17

2 Answers2

2

You don't call setTimeout() inside a for loop. You replace the for loop with setTimeout():

let loop = 0;
function loop () {
    console.log("hi");
    x++;

    if (x<3) {
        setTimeout(loop, 10000);
    }
}
loop();

This is the traditional way of doing it. You can use a Promise with async/await in modern js to use the for loop again:

// First we need a promisified setTimeout:
function delay (ms) {
    return new Promise((resolve,reject) => setTimeout(resolve,ms));
}

async function test () {
    for (let i=0;i<3;i++){
        await delay(10000);
        console.log("hi");
    }
}

test();
slebetman
  • 109,858
  • 19
  • 140
  • 171
  • @V.Jain maybe because this solution is already covered in the flagged duplicate – Ayush Gupta Jul 24 '20 at 15:37
  • Even if thats true, I thought you downvote incorrect or misleading answers? I just wanted to know what about these answers are incorrect/misleading. – Vishal Jain Jul 24 '20 at 15:43
0

Javascript is asynchronous which means your timers start immediately rather than each timer blocking until done, and they all execute after roughly 10s plus a few ticks.

If you want you can try setInterval with a counter to clear it:

var counter = 0;
var interval = setInterval(function(){
   console.log("hi");
   counter+=1;
   if (counter == 3) { clearInterval(interval); }
}, 10000);

You can probably work out an alternative using setTimeout as well.

Nick M
  • 2,424
  • 5
  • 34
  • 57