0

I have a function that writes some text in the console after 3 seconds in the for a loop. Here it is:

const arr = [0, 0, 0, 0];
for (var i = 0; i < arr.length; i++) {
  setTimeout(function() {
    console.log("Index: " + i + ", element: " + arr[i]);
  }, 3000);
}

The problem is that the output in the console is not correct. It is as follows:

Index: 4, element: undefined
Index: 4, element: undefined
Index: 4, element: undefined
Index: 4, element: undefined

But I expect it to be like this:

Index: 0, element: undefined
Index: 1, element: undefined
Index: 2, element: undefined
Index: 3, element: undefined

Please, tell me what I’m doing wrong.

  • It's because, whenthe timeout has come, the for loop is finished and `i = 4` – Maxime Girou Nov 21 '19 at 16:54
  • you can give `i` as a parameter instead of closing over it, `var i = 4; setTimeout(function(a){ console.log(a) },3000,i); i = 0; console.log(i)`, the `a` will be 4, even i is set to 0 immediatly – birdspider Nov 21 '19 at 16:57

3 Answers3

2

for loop doesn't waiting this time, it compiles the result and then presents the last one.

Get setTimeout function outside of for loop. :

setTimeout(function() {
  const arr = [0, 0, 0, 0];
  for (var i = 0; i < arr.length; i++) {
    console.log("Index: " + i + ", element: " + arr[i]); 
  } 
}, 3000);
Aksen P
  • 4,564
  • 3
  • 14
  • 27
2

You should use let instead of var to scope the inner-loop.

All at once...

const arr = [0, 1, 2, 3];
for (let i = 0; i < arr.length; i++) {
  setTimeout(function() {
    console.log("Index: " + i + ", element: " + arr[i]);
  }, 1000);
}

One-by-one...

If you want to print each one in a fixed-interval, multiply the timeout by the current index.

const arr = [0, 1, 2, 3];
for (let i = 0; i < arr.length; i++) {
  setTimeout(function() {
    console.log("Index: " + i + ", element: " + arr[i]);
  }, i * 1000);
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
0

Another way of skinning the same cat - using forEach

const arr=[ 0, 0, 0, 0 ];
arr.forEach( ( value, index )=>{
    setTimeout( ()=>{
        console.info('Index: %d, element: %s', index, value );
    },1000 );
});
Professor Abronsius
  • 33,063
  • 5
  • 32
  • 46