1

我编写了这段代码来计算秒数(用 decisec 和 centisec)。

    You've wasted time <span id="alltime">0.00</span> seconds.

    <script type="text/javascript"> 
    function zeroPad(num,count)
    {
    var numZeropad = num + '';
    while(numZeropad.length < count) { numZeropad = "0" + numZeropad; }
    return numZeropad; }
    function counttwo() {
    tall = document.getElementById('alltime').innerHTML;
    if(parseFloat(tall) < 1.00) {     tnew2 = tall.replace('0.0','').replace('0.','');    }
        else {    tnew2 = tall.replace('.','');    }
    tnum = parseInt(tnew2) + 1;
       //check if have to add zero 
if(tnum >= 100) { tstr1 = tnum + ''; }
        else { tstr1 = zeroPad(tnum,3); }
    tlast = tstr1.substr(0,tstr1.length - 2) + '.' + tstr1.substr(tstr1.length - 2);
        document.getElementById("alltime").innerHTML = tlast;
    }
    var inttwo=setInterval("counttwo()",10);
    </script>

在 HTML 文件中运行。

它运行良好,但是当我使用 Firefox 4 并运行代码时。当它在某些数字上(随机像 12.20、4.43)时,它似乎有点滞后(在计数之前停下来)。我尝试将“counttwo()”更改为 counttwo,但这无济于事。

我已经告诉我的一些朋友也可以在 Firefox 4 上运行。他们说它根本不落后。这个原因是因为我的电脑吗?还是我的火狐?或者是其他东西 ?

提前致谢!

PS。在这里小提琴:http: //jsfiddle.net/XvkGy/5/镜像:http ://bit.ly/hjVtXS

4

5 回答 5

2

当您使用 setInterval 或 setTimeout 时,由于多种原因,时间间隔并不准确。它依赖于其他运行的 javascript、浏览器、处理器等。您必须将 +- 15 毫秒的可靠性视为理所当然的 afaik。也可以看看 ...

于 2011-04-26T15:01:24.520 回答
1

这是很多计算,所以在某些计算机上,是的,它可能会滞后(如果它是史前计算机或者用户的处理器真的很忙),如果我是对的,那东西也不适用于 Chrome 的 V8 ,因为如果您切换选项卡,该脚本将冻结,并且仅在您返回该选项卡时恢复执行。

于 2011-04-26T14:57:37.310 回答
1

如果您只是经常看到暂停,您可能会看到垃圾收集或循环收集暂停。

您可以通过将您的javascript.options.mem.log首选项切换为 true来测试这一点about:config,然后在脚本运行时观察错误控制台的“消息”选项卡。如果 GC/CC 消息与您的暂停相关,那么它们就是您所看到内容的解释。

至于为什么您看到它而其他人没有...如果您禁用所有扩展程序,您会看到问题吗?

于 2011-04-26T15:36:39.250 回答
1

问题setInterval在于它最终可能导致备份。发生这种情况是因为 JavaScript 引擎尝试在间隔(在您的情况下为 10 毫秒)执行函数,但如果执行时间超过 10 毫秒,JS 引擎开始尝试在当前间隔停止之前执行下一个间隔(这真的只是意味着它排队等待上一个回调完成后立即运行)。

由于 JavaScript 执行单线程(HTML 5 中的 Web Worker 除外),这可能会导致 UI 或 DOM 更新暂停,因为它会持续处理来自setInterval. 在最坏的情况下,整个页面可能会永久无响应,因为未完成的setInterval执行堆栈变得越来越长,永远不会完全完成。

除了少数例外,通常认为使用setTimeout(并setTimeout在执行回调后再次调用)而不是setInterval. 使用setTimeout,您可以确保只有一个超时排队。而且由于计时器无论如何只是近似值(仅仅因为您指定 10ms 并不意味着它将在 10ms 发生),因此您通常不会从使用setIntervalover中获得任何收益setTimeout

使用示例setTimeout

var count = function(){
    // do something

    // queue up execution once again
    setTimeout(count, 10);
};

count();

您可能会在某些浏览器上看到暂停而不是其他浏览器的原因之一是因为并非所有 JavaScript 引擎都是平等的 :)。有些比其他更快,因此不太可能最终得到setInterval备份。

于 2011-04-26T15:13:11.350 回答
0

不同的浏览器使用不同的 JavaScript 引擎,因此这段代码可能只是找到了 Firefox 的 JägerMonkey 脚本引擎存在问题的地方。计数本身似乎没有任何明显的低效率..

如果它适用于您朋友安装的 FF4,那么这对您来说可能只是一个孤立的问题,您无法通过更改代码来做很多事情。

于 2011-04-26T14:56:26.860 回答