0

My setTimeout statements are making function calls instantly instead of waiting the time I specified and I'm not sure why. It should take 10 seconds for the for loop and then 110 seconds to change a boolean value from T to F.

    for(var c = 0; c < 10; c++)
    {
        setTimeout(function()
        {
        gold = gold + clickerPower;
        $("#totalGold").html("Gold: " + gold);
        console.log("Clicked!");
        }, 1000);

    }
    setTimeout(function(){frenzyActive = false;}, 110000);
gm95
  • 3
  • 2

3 Answers3

2

Starting a timeout is an asynchronous operation. setTimeout accepts a function as it's first argument because it's registering that callback function to be invoked at a later time. Every iteration of the JavaScript event loop it checks to see if the appropriate time has passed and if so then it fires the registered callback. Meanwhile it's still moving on to run other code while it waits.

Your for loop is not waiting for anything. It iterates to 10 super fast and all you've done is register ten callbacks to fire all at the same time in exactly one second (the time is specified in milliseconds by the way, so 1000 = 1 second).

You need setInterval.

var count = 0;
var intervalId = setInterval(function () {
  gold = gold + clickerPower;
  $('#totalGold').html('Gold: ' + gold);
  console.log('Clicked!');
  count++;
  if (count === 10) {
    clearInterval(intervalId);
    frenzyActive = false;
  }
}, 1000);

That function will run once every second and increment a count variable each time. When it reaches 10 we call clearInterval and give it the intervalId returned from setInterval. This will stop the interval from continuing.

Take a gander at this post I wrote back when I too was confused about asynchronous callbacks :)

http://codetunnel.io/what-are-callbacks-and-promises/

I hope that helps :)

Good luck!

CatDadCode
  • 58,507
  • 61
  • 212
  • 318
0

It will not take 10 seconds to execute the loop. Look will execute immediately and the anonymous function will be enqueued 10 times to be executed after 1 second.

The last call to setTimeout will cause the anonymous function to be executed after 110 seconds.

To ensure that the anonymous function within the loop is called sequentially, 10 times, after a gap of 1 second each, do the following:

var c = 0;
setTimeout(function() {
    if(c < 10) {
        gold = gold + clickPower;
        console.log("Clicked");
        c++;
        setTimeout(arguments.callee, 1000);
        //^^ Schedule yourself to be called after 1 second
    }
}, 1000);
gvaish
  • 9,374
  • 3
  • 38
  • 43
0

I did come across this challenge today, and the answer provided by @Guarav Vaish set me on a path to success. In my case, I am using ES6 syntax and its worth noting that the arguments.callee is deprecated. However, here is how I'd write the same solution as contributed by Vaish:

var c = 0;
setTimeout(function named() {
    if(c < 10) {
        gold = gold + clickPower;
        console.log("Clicked");
        c++;
        setTimeout( ()=>{ named() }, 1000);
        //^^ Schedule yourself to be called after 1 second
    }
}, 1000);

Note: I am simply using a named function in place of the anonymous one in the original solution. Thank you. This was really helpful