使JavaScript间隔与实际时间同步

时间:2018-12-21 23:19:03

标签: javascript time

我希望使秒与实时(new Date())秒同步,以便在页面加载第二秒时可以正常工作。

setInterval(() => {
    console.log("hey im not synchronized");
}, 1000);

有可能吗?

2 个答案:

答案 0 :(得分:2)

  

有可能吗?

是的,像这样:

1264px

答案 1 :(得分:0)

为此,您想要的是一个自同步定时循环。基本的想法是不是使用setInterval(),而是每次计算您希望循环下次触发多少毫秒,然后使用setTimeout()等到那时

这是一个基本示例:

function oncePerSecond(callback) {
    var timerFunc = function () {
        // get the current time rounded down to a whole second (with a 10% margin)
        var now = 1000 * Math.floor(Date.now() / 1000 + 0.1);
        // run the callback
        callback(now);
        // wait for the next whole second
        setTimeout(timerFunc, now + 1000 - Date.now());
    };
    timerFunc();
}

// create a demo timer
oncePerSecond(function (now) {
    document.getElementById('local').textContent = new Date(now).toString();
});

// add an artificial 0.5 second delay for the second timer
setTimeout(function () {
    oncePerSecond(function (now) {
        document.getElementById('utc').textContent = new Date(now).toUTCString();
    });
}, 500);
<p>The local time is now: <span id="local">...</span></p>
<p>The UTC time is now: <span id="utc">...</span></p>

请注意,即使上面摘录中的两个计时器间隔半秒启动,但它们在第一次更新后立即同步。

+ 0.1中出现有趣的Math.floor(Date.now() / 1000 + 0.1)软糖的原因是,不能保证计时器有时不会提早触发,只是在时钟滴答之前几毫秒。 0.1秒的偏移量可确保在这种情况下可以将当前时间四舍五入,但在通常情况下,我们仍会在第一次更新时(或在可能的意外延迟之后)将时间四舍五入。

为获得更好的结果,您可能希望将此技术与requestAnimationFrame()结合使用,以使您的计时器不会在用户处于待机状态时不必要地触发。查看另一个标签:

function oncePerSecondAnim(callback) {
    var frameFunc = function () {
        // get the current time rounded down to a whole second (with a 10% margin)
        var now = 1000 * Math.floor(Date.now() / 1000 + 0.1);
        // run the callback
        callback(now);
        // wait for the next whole second
        setTimeout(timerFunc, now + 1000 - Date.now());
    }, timerFunc = function () {
        requestAnimationFrame(frameFunc);
    };
    timerFunc();
}

// create a demo timer
oncePerSecondAnim(function (now) {
    document.getElementById('local').textContent = new Date(now).toString();
});

// add an artificial 0.5 second delay for the second timer
setTimeout(function () {
    oncePerSecondAnim(function (now) {
        document.getElementById('utc').textContent = new Date(now).toUTCString();
    });
}, 500);
<p>The local time is now: <span id="local">...</span></p>
<p>The UTC time is now: <span id="utc">...</span></p>