0

I want to call a function in a cycle with setTimeout(), and also pass the counter as a parameter. Here's what I tried:

<!DOCTYPE html>
<html><body>

<button onclick="timed1()">Display alerts</button>

<script>
function timed1() {
 for (i=1; i<4; i++){
  setTimeout(
     (function(i){ alert(i) })(i), 1000*i
   );
 }
}
</script>

</body></html>

Function calls are done with correct values, but immediately instead of the intervals I wanted. I have read this and this SO questions but unfortunately don't see yet what should I change in my case.

Vasily A
  • 8,256
  • 10
  • 42
  • 76

4 Answers4

1

You can use let here if you want to bind different values of i to the setTimeout function

function timed1() {
    for (let i=1; i<4; i++){
      setTimeout(function() { 
          alert(i) 
      }, 1000*i)
    }
}
timed1()
mehulmpt
  • 15,861
  • 12
  • 48
  • 88
1

The expression (function(i){ alert(i) })(i) does not return a function for setTimeout to call. If you're going the IIFE way, make sure to return a new function from it:

setTimeout((function(i) {
    return function() {
        alert(i);
    };
})(i), 1000 * i);

With ES2015+ a far better readable equivalent can be realized:

for (let i = 1; i < 4; i++) {
    setTimeout(() => alert(i), 1000 * i);
}
mehulmpt
  • 15,861
  • 12
  • 48
  • 88
JJWesterkamp
  • 7,559
  • 1
  • 22
  • 28
1

You're swimming on IIFE (Immediately Invoked Function Expression).

You're calling your function immediately.

setTimeout(
   (function(i){ alert(i) })(i), 1000*i
);                           ^

The scope of your variable i is open, you need to use let keyword.

for (i = 1; i < 4; i++) {
     ^

Look at this code snippet

function timed1() {
  for (let i = 1; i < 4; i++) {
    setTimeout(
      function() {
        alert(i)
      }, 1000 * i);
  }
}
<button onclick="timed1()">Display alerts</button>
Ele
  • 33,468
  • 7
  • 37
  • 75
1

The setTimeout function allows you to pass arguments to the callback function, like so:

function timed1() {
  for (i=1; i<4; i++){
    setTimeout(alert, 1000 * i, i);
  }
}

timed1()

Any arguments after the time are passed along to the callback.

Sidney
  • 4,495
  • 2
  • 18
  • 30