Reputation: 3813
I have a stopwatch that must call setInterval and increase a variable every millisecond, so that I get the ElapsedTime when I call Stop(). This I will use to measure the time necessary for a request, but for the sake of simplicity i just added a sleep function
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
var Stopwatch =
{
ElapsedTime: 0,
CounterId :0,
IncrementElapsedTime:function(){
this.ElapsedTime++;
console.log("incremented to: " + this.ElapsedTime);
},
Start: function(){
this.CounterId = setInterval(this.IncrementElapsedTime(), 1);
},
Stop: function(){
clearInterval(this.CounterId);
}
}
Stopwatch.Start();
sleep(500);
Stopwatch.Stop();
console.log("final result: " + Stopwatch.ElapsedTime);
I expect that since I waited 500 milliseconds, the ElapsedTime after calling Stop is exactly that, 500. But the ElapsedTime just shows 1 instead of 500. What do I do wrong? Thanks
--
Explanation - after reading the comments i understood that my intention is simlpy not clear - all I want is to get an elapsed time, in milliseconds, between the interval start and clear. Can someone point me in the right direction is this code is not the best way to do this, thanks
Upvotes: 1
Views: 95
Reputation: 10565
There are two points to look into. Inside the start, you cannot refer this
in setInterval
. This needs a global reference as it executes detached from the object from where setInterval
is triggered. Second point is the script executor goes busy with your sleep()
and forgets to execute what you wanted to. Moreover, setInterval
should not be used for precised applications. The following code counts only till 2646
on my browser, even though I asked to stop timer after 10000ms
:
var Stopwatch =
{
ElapsedTime: 0,
CounterId :0,
IncrementElapsedTime:function(){
this.ElapsedTime++;
console.log("incremented to: " + this.ElapsedTime);
},
Start: function(){
this.CounterId = setInterval(function(){Stopwatch.IncrementElapsedTime();}, 1);
},
Stop: function(){
clearInterval(this.CounterId);
}
}
Stopwatch.Start();
setTimeout(function() {
Stopwatch.Stop();
console.log("final result: " + Stopwatch.ElapsedTime);
}, 10000);
Upvotes: 1
Reputation: 21575
This is due to JavaScript being only sequentially single threaded and not multi-threaded. This means that while the busy loop sleep()
is running, there cannot be any calls from setInterval
, which leads to it being only called once before .Stop()
is called.
As long as the elapsed time isn't being stopped by busy loops or blocking execution (like prompts), you will get a correct value from .Stop()
.
Upvotes: 1