I want to fire a recursive function every 10 milliseconds, but setTimeout doesn't seem to take any value under 100, no matter what I put.
decrementCountdown = function() {
console.log('fired');
t = setTimeout("decrementCountdown()", 100);
}
Why can't I set a value under 1000 milliseconds?
EDIT : Looks like my timer is firing correctly...the problem is when I use it to call a function ( like Jquery's html() ). Even though setTimeout is calling the function at correct intervals, it won't fire any faster than 100 milliseconds.
Anyone know how I can make a countdown timer on my page that counts down by 10 milliseconds?
I want to fire a recursive function every 10 milliseconds, but setTimeout doesn't seem to take any value under 100, no matter what I put.
decrementCountdown = function() {
console.log('fired');
t = setTimeout("decrementCountdown()", 100);
}
Why can't I set a value under 1000 milliseconds?
EDIT : Looks like my timer is firing correctly...the problem is when I use it to call a function ( like Jquery's html() ). Even though setTimeout is calling the function at correct intervals, it won't fire any faster than 100 milliseconds.
Anyone know how I can make a countdown timer on my page that counts down by 10 milliseconds?
Share Improve this question edited Jan 17, 2012 at 3:34 zakdances asked Jan 17, 2012 at 3:13 zakdanceszakdances 23.7k32 gold badges108 silver badges174 bronze badges 2- 1 What makes you think it doesn't? Your example doesn't prove anything. – j08691 Commented Jan 17, 2012 at 3:15
- Because whether I put 999 or 1 it fires at exactly the same rate...1 second. This is a simplified example, my real code uses this function to decrement a countdown timer. Would it be more helpful if I included that? – zakdances Commented Jan 17, 2012 at 3:21
3 Answers
Reset to default 7A better example is:
var stop = 0;
decrementCountdown = function() {
console.log(new Date().getTime());
stop++;
if (stop<10) t = setTimeout("decrementCountdown()", 100);
}
decrementCountdown();
As you should see, the timeout is triggered about every 100ms (jsFiddle).
I tried your example and it seemed to work fine.
For what it's worth I'd save on the constant redeclaration of setTimeout by using
function decrementCountdown()
{
/*Do your thing*/
}
setInterval(decrementCountdown, 100);
Here's a page you can run that will tell you exactly what the variations are for setTimeout()
in your browser on your system. It runs 10,000 setTimeout(fn, 1)
operations and records the average, max and min latency between calls and outputs that to the screen.
setTimeout()
does have a minimum value that it will honor. It varies a bit by browser, but it is typically in the range of 10-20ms (though it can be smaller or larger - it's up to the browser). This is called "clamping". It's purpose is to protect the browser event queue from too much javascript execution and not enough time to do other things (like service other user events, repaints, etc...).
But, that only means that the browser won't fire one sooner than that minimum value, it doesn't mean that you will always get one that quickly. Javascript is single threaded so if the browser is busy, the setTimeout()
won't happen until there is no more javascript executing and the next timer event gets to the front of the queue.
Furthermore, timers will slow down in some modern browsers, when the page with the timer is not the current tab. You can see that in the above page by switching to another tab while it's running and see that you get a slower avg time.
For those that are curious, here's the code from that page:
var lastTime = new Date();
var cumDiff = 0;
var minDelta = 1000000;
var maxDelta = 0;
var cnt = 0;
var nowElem = document.getElementById("now");
var deltaElem = document.getElementById("delta");
var minDeltaElem = document.getElementById("minDelta");
var maxDeltaElem = document.getElementById("maxDelta");
function run() {
var now = new Date().getTime();
var diff = now - lastTime;
cumDiff += diff;
minDelta = Math.min(diff, minDelta);
maxDelta = Math.max(diff, maxDelta);
cnt++;
var avgDelta = cumDiff / cnt;
lastTime = now;
nowElem.innerHTML = now;
deltaElem.innerHTML = avgDelta.toFixed(1);
minDeltaElem.innerHTML = minDelta;
maxDeltaElem.innerHTML = maxDelta;
if (cnt < 10000) {
setTimeout(run, 1);
}
}
setTimeout(run, 1);
Disclaimer: some older browsers don't have very accurate Date()
functions (only accurate to within 10-20ms) so this data won't be very accurate in one of those older browsers.