Javascript setTimeout不允许100毫秒以下的间隔

时间:2012-01-17 03:14:00

标签: javascript timer

我想每10毫秒触发一次递归函数,但是无论我放的是什么,setTimeout似乎都不会取任何小于100的值。

decrementCountdown = function() {
    console.log('fired');
    t = setTimeout("decrementCountdown()", 100);
}

为什么我不能在1000毫秒以下设置一个值?

编辑:看起来我的计时器正在正常启动...问题是我用它来调用一个函数(比如Jquery的html())。即使setTimeout以正确的间隔调用函数,它也不会以100毫秒的速度激活。

任何人都知道如何在我的页面上倒数计时器,倒计时10毫秒?

3 个答案:

答案 0 :(得分:7)

更好的例子是:

var stop = 0;
decrementCountdown = function() {
    console.log(new Date().getTime());
    stop++;
    if (stop<10) t = setTimeout("decrementCountdown()", 100);
}

decrementCountdown();

正如您所看到的,大约每100毫秒(jsFiddle)触发超时。

答案 1 :(得分:1)

这是一个page you can run,可以准确地告诉您系统浏览器中setTimeout()的变体。它运行10,000 setTimeout(fn, 1)次操作,并记录调用和输出到屏幕的平均,最大和最小延迟。

setTimeout()确实具有最低价值。它通过浏览器略有不同,但通常在10到20毫秒的范围内(尽管它可以更小或更大 - 它取决于浏览器)。这被称为&#34; clamp&#34;。它的目的是保护浏览器事件队列免于过多的javascript执行而没有足够的时间来做其他事情(比如服务其他用户事件,重新绘制等等)。

但是,这只意味着浏览器不会比那个最小值更快地发射一个,它并不意味着你总能快速获得一个。 Javascript是单线程的,所以如果浏览器忙,setTimeout()不会发生,直到没有更多的javascript执行并且下一个计时器事件到达队列的前面。

此外,当带有计时器的页面不是当前选项卡时,计时器在某些现代浏览器中会变慢。您可以在上面的页面中看到它在运行时切换到另一个标签,并看到您的平均时间较慢。

对于那些好奇的人,请点击该页面的代码:

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);

免责声明:某些较旧的浏览器不具备非常准确的Date()功能(仅精确到10-20毫秒内),因此这些数据在其中一个较旧的浏览器中不会非常准确。 / p>

答案 2 :(得分:1)

我尝试了你的例子,似乎工作正常。

为了它的价值,我将通过使用

来保存对setTimeout的不断重新声明
function decrementCountdown()
{
    /*Do your thing*/
}
setInterval(decrementCountdown, 100);