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);
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!
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);
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
Related
This time go faster if is called 2 times, 3 times faster and so on.
function startIdleTime() {
var ciclo;
function startSlidercicle() {
ciclo = setInterval( function() {
let seconds = parseInt(sessionStorage.getItem('idle'));
seconds += 1;
sessionStorage.setItem('idle', seconds);
}, 1000);
}
// start idle counter
if (!sessionStorage.getItem('idle')) {
alert('non esiste timer, lo imposto')
sessionStorage.setItem('idle', 0);
alert(3)
}
if (sessionStorage.getItem('idle') > 15) {
anotherFunction();
}
if (sessionStorage.getItem('idle') < 15 || !sessionStorage.getItem('idle')) {
clearInterval(ciclo);
startSlidercicle();
}
}
I need to set idle time. When 15 i'll call an other function,
if <= 15 I reset only a counter to 0
But if is called few times my count go faster then 1sec }, 1000);)
Looks like the interval is not cleared before instantiating a new one. The result will be several intervals that will be executed with a different phase, and it will look like it's running with a shorter interval.
The reason for this behavior is that you are not clearing the interval, because you are creating a new ciclo variable every time you call the startIdleTime function. Probably you want the variable ciclo to be global, in order to share the interval handler across the function calls. You need to widen the scope, and to widen the scope you can just move the variable declaration out of the function definition:
var ciclo;
function startIdleTime() {
function startSlidercicle() {
Also note that in the following line:
sessionStorage.getItem('idle') < 15 || !sessionStorage.getItem('idle')
the second part is never evaluated. Let's suppose that getItem returns null: then null < 15 is true, so the check becomes useless
I am trying to use setTimeout for a performance test using console.time() and console.timeEnd(). However, setTimeout() isn't delaying the for() loop.
Here is the JS Fiddle:
// Start the timer.
console.time('testFor');
for ( i = 0; i < 5; i++ ) {
setTimeout( console.log('The number is ' + i), 2000 );
}
// End the timer, get the elapsed time.
console.timeEnd('testFor');
How can I make setTimeout() work in my script and why is it not working for me?
Others have already suggested excellent solutions to your problem - I'd like to offer a closer examination of what was happening with your code.
setTimeout doesn't delay the advancement of your code (like sleep does in other languages) but instead defers running another block of code. It's a weird concept that can be hard to understand; consider the following example:
console.time("Main Program");
console.time("Defered Code");
setTimeout(deferedCode, 1000);
console.timeEnd("Main Program");
function deferedCode() {
console.timeEnd("Defered Code");
}
If we look at the console after running this code, we'll see "Main Program" print out almost immediately, and "Defered Code" roughly a second later.
We've asked setTimeout to run the function deferedCode at a time 1000 ms in the future, and then let the rest of the code run.
Notice also that deferedCode is passed to setTimeout without (). We're passing the function itself and not the result of deferedCode to setTimeout so that setTimeout can choose when to run it.
You could do this without a loop, just using recursion:
var i = 0;
var logNumber = function(){
console.log('The number is ' + i);
i++;
if(i < 5){
setTimeout(logNumber, 2000);
}
}
logNumber();
setTimeout is asynchronous. If you want to call a certain piece of code at regular intervals, use the setInterval function.
I think this code is close to what you are trying to do:
// Start the timer.
console.time('testFor');
var i = 0;
var finish = 5;
var t = setInterval(function() {
if (i < finish) {
console.log('The number is ' + i);
i++;
} else {
clearInterval(t);
// End the timer, get the elapsed time.
console.timeEnd('testFor');
}
}, 2000);
Learning about callbacks and the solution to this problem eludes me.
It should print a number every second counting down until zero. Currently, it logs the numbers from 10 - 0 but all at once and continues in an infinite loop.
Please help me to gain a better understanding of this situation. I have read up on callbacks and have a conceptual understanding but execution is still a bit tricky.
var seconds = 0;
var countDown = function(){
for(var cnt = 10; cnt > 0; cnt--){
setTimeout(function(x){
return function(){
seconds++
console.log(x);
};
}(cnt), seconds * 1000);
}
}
countDown()
The way your code is working now, it executes a for loop with cnt going from 10 to 1. This works. On each iteration, it schedules a new function to be run in seconds * 1000 milliseconds, carefully and properly isolating the value of cnt in x each time. The problem is that seconds is 0, and it will only be changed once a callback executes; but by the time a callback executes, all of them will already have been scheduled for execution. If you need seconds * 1000 to vary while you’re still scheduling them all (while the for loop is still running), you need to change seconds in the loop, rather than inside one of the callbacks.
Read up on IIFEs to see how they work. In this situation, you're creating a closure of the value you want to print. You had the right idea, but your syntax was off.
var seconds = 0;
var countDown = function () {
var cnt = 10;
// simplify your loop
while (cnt--) {
// setTimeout expects a function
// use an IIFE to capture the current value to log
setTimeout((function (x) {
// return the function that setTimeout will execute
return function (){
console.log(x + 1);
};
}(cnt)), (++seconds) * 1000);
}
};
countDown();
I'm not understanding why this function outputs 1-5 in successive order as intended, but at 1 second intervals rather than 1,2,3, etc. seconds. I'm unfamiliar with the setTimeout function and I understand that something is going on with the arguments to the function here that I'm not seeing.
var counter = function() {
for (var i = 1; i <= 5; i++) {
(function(x){
setTimeout(function timer() {
console.log(x);
}, (x * 1000));
})(i);
}
};
You can avoid the for loop by calling it recursively, just pass the start and stop index.
var counter = function (x, y) {
setTimeout(function timer() {
console.log(x);
if (x != y) counter((x + 1),y);
}, (x * 1000));
};
counter(1, 5);
Fiddle demo
Because you are immediately placing all your calls to setTimeout. So, during the same event, JS receives the instruction to call timer: after 1000ms, after 2000ms, after 3000ms, after 4000ms and after 5000ms. Which is exactly what it does, so timer is called every 1 second.
If you wish to progressively increase the interval, your loop should be rewritten as a recursive loop, in which the next call to setTimeout is performed by timer.
As #putvande said you are setting all 5 timeouts at the same time with different intervals.
var counter = function(){
for (var i=1; i<=5; i++) {
console.log('setting timer for ' + i);
(function(x){
setTimeout( function timer(){
console.log(x);
}, (x*1000) );
})(i);
}
};
counter();
An extra log statement show this. Your timers are firing at the right interval, 1st one at 1 second, 2nd one at 2 seconds, etc.
I want to know, How it works the setInterval function.
First: I have simple example (Live demo)
Also the code below.
HTML:
<div id="elem"></div>
<div id="count"></div>
<div id="Timer"></div>
Javascript:
var s = 10;
var count = 0;
if (s == 20) alert("S= 20");
var timer = setInterval(function () {
if (count < 50) {
count++;
document.getElementById('count').innerHTML = "Counter: " + count;
}
else {
clearInterval(timer);
document.getElementById('count').innerHTML = "Counter: End Of Count";
}
}, 50);
s = 20;
document.getElementById('elem').innerHTML = "variable 's': " + s;
document.getElementById('Timer').innerHTML = "Timer value: " + timer;
if (s == 20) alert("S= 20");
All I want is how the function it works.
After implement the code of function , is it return to the beginning of code at top page , or return to implement the function code again until use clearInterval function.
Anybody help me please.
In your code, you are supplying an anonymous function to setTimeout.
The anonymous function supplied to setInterval is called asynchronously. The anonymous function cannot run for the first time until the current function is complete. The call to setInterval(function() {...}) is registering your anonymous function for execution every 50ms; it does not execute immediately.
Your program flow runs like this:
set initial variables
check if s == 20
register (not execute) the anonymous function with setInterval
set s = 20
print results
check if s == 20
end of your code blcok
...
50ms later, the first call to your anonymous setTimeout function finally happens
Repeatedly call the anonymous function every 50ms
Takeaway point: If you need certain operations to happen after the anonymous function completes, put those operations inside the anonymous function itself. In your code, I suspect you want some lines that currently come after the setTimeout call and place them inside the else block in your anonymous function.
setInterval keeps calling the enclosed function repeatedly till clearinterval is called. the delay can be given in seconds 1000 = 1 sec, since you have given a small delay of 50 the function is called repeatedly in quick succession till it reaches the 50 limit