Reputation: 91
I was recently making a timer object and a ticking function that would tick every second according to a setTimeout loop. However, there was no delay in the ticking. If you try out the below code, you will find that the time number has increased to the thousands in only a few seconds. What, if anything, am I doing wrong?
<html>
<head>
</head>
<button onclick="startTimer()">Start</button>
<button onclick="stopTimer()">Stop Timer</button>
<button onclick="readTimer()">Read Timer</button>
<script>
function tick(){
console.log("TICK TOCK");
if(this.running == true){
this.time += 1;
console.log("HELLO!");
setTimeout(this.tick(), 1000, $(this));
}
}
function start(){
this.running = true;
this.tick();
}
function read(){
return this.time;
}
function stop(){
this.running = false;
}
function reset(){
if(this.running == false){
this.time = 0;
}else {
this.time = 0;
}
this.tick();
}
function timer(){
this.running = false;
this.time = 0;
this.start = start;
this.read = read;
this.stop = stop;
this.reset = reset;
this.tick = tick;
}
var t = new timer();
function startTimer(){
t.start();
}
function stopTimer(){
t.stop();
}
function readTimer(){
alert("This is the current Timer Reading: " + t.time);
}
</script>
</html>
Upvotes: 0
Views: 163
Reputation: 351369
You are passing an executed function, instead of a function reference to setTimeout
. To pass the function itself, remove the parentheses. Secondly, to make sure this
will still be the current this
when tick
is eventually invoked, use .bind(this)
.
Note that the third argument of setTimeout
would pass that value to tick
, which is of no use in your case. NB: That $(this)
is probably a remnant of some other code, since the $
would be typically used with jQuery, which you are not using.
So taking that all together, do:
setTimeout(this.tick.bind(this), 1000)
Upvotes: 1
Reputation: 2708
Your error is that you call setTimeOut
on this.tick()
. When you call this
inside the tick()
function, you are already referring to the tick
function, so you want to use setTimeout(this, 1000);
and your timer will work properly.
See this fiddle for solution: https://jsfiddle.net/sg7yf6r4/
Read more about the issue: Javascript objects calling function from itself
Upvotes: 1
Reputation: 1745
The first parameter of setTimeout
should be a function. However, you are passing it the result of a function. So instead of setTimeout(this.tick(), 1000, $(this));
you should use setTimeout(this.tick, 1000, $(this));
.
Upvotes: 1