【问题标题】:Time-sensitive application in javascript [duplicate]javascript中的时间敏感应用程序[重复]
【发布时间】:2017-01-02 13:31:14
【问题描述】:

我需要每 1 秒生成一个事件。我正在测试 setTimeout 函数如下:

   window.onload = function() {
        var oldTime = Date.now();

        setTimeout(function printTime() {
            newTime = Date.now();
            console.log(newTime - oldTime);
            oldTime = newTime;
            setTimeout(printTime, 1000);
        }, 1000);
    }

它返回带有一点偏移量的 1:

testTimeout.js:6 1005
testTimeout.js:6 1006
2testTimeout.js:6 1001
testTimeout.js:6 1006
testTimeout.js:6 1005
testTimeout.js:6 1006
testTimeout.js:6 1005

偏移量从何而来?是因为oldTime和newTime计算的原因吗?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    我需要每 1 秒生成一个事件。

    没有办法精确地做到这一点。

    传递给setTimeout 的时间是您的代码将运行的最短保证时间,而不是确切时间。

    时间表示JS引擎将该函数推送到Event Queue的毫秒数。一旦函数进入事件队列,它在队列中存在的所有当前任务之后运行,例如事件和其他计时器,这将产生延迟。

    此外,当任何常规 JS 代码正在运行时,无法从事件队列中执行任何任务,这也可能造成小的延迟。

    比如这个函数test:

    setTimeout(function test() {
      console.log('second');
    }, 0);
    for (i = 0; i < 1000000; i++); // the number 1000000 is an arbitrary big number
    console.log('first');

    将在它下面的循环完成后运行,这将超过0 毫秒。

    事实上,如果该循环是无限的,setTimeout 回调将永远不会触发。


    注意:正如cmets中的nnnnnn所说,实际最小时间为per the HTML5 spec,其中setTimeout将一个函数推送到Event Queue是 4ms,不管我们是否放得更少。以前这个限制是 10 毫秒。

    MDN

    事实上,4 ms 是由 HTML5 规范指定的,并且在 2010 年及以后发布的浏览器中是一致的。在 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2) 之前,嵌套超时的最小超时值为 10 毫秒。

    【讨论】:

    • 换句话说,您无法安排函数在准确时间运行。 (另外,关于 0ms 超时,即使在它之后没有长时间运行的循环,它在运行之前仍然至少需要 4ms,因为浏览器会将较小的延迟舍入到 4ms - 尽管您关于其他代码必须首先完成的观点仍然有效。 )
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多