3

我有 2 个 node.js 网络服务器。我在网络服务器中缓存数据。我根据系统时间同步缓存加载/清除。我已经完成了所有主机的时间同步。

现在我使用以下代码每 15 分钟清除一次缓存:

millisTillNexthour = "Calculate millis remaining until next hour"

setTimeout(function() {
  setInterval(function() {
    cache.clear();
  }, 60000*15);
}, millisTillNexthour);

我的期望是,即使这个过程永远运行,缓存也会在一天中的每个小时的第 15 分钟被清除一次。

我的问题是:setInterval 会随时间漂移吗?

例如:现在它清除缓存10:00 10:15 10:30 10:45 11:00 ......

会不会发生 setInterval 不是 10:15 系统时间,而是在 10:20 系统时间执行,而它应该在 10:15 清除缓存?

我不确定这是如何工作的。请阐明一些观点。我希望我能很好地解释我的问题。

4

6 回答 6

2

我在这里聚会可能有点晚了,但这就是我刚才解决这个特殊的时间滑动问题的方法,使用递归调用的 setTimeout() 函数而不是使用 setInterval()。

var interval = 5000;
var adjustedInterval = interval;
var expectedCycleTime = 0;

function runAtInterval(){
    // get timestamp at very start of function call
    var now = Date.now();

    // log with time to show interval
    console.log(new Date().toISOString().replace(/T/, ' ').replace(/Z/, '') + " runAtInterval()");

    // set next expectedCycleTime and adjustedInterval
    if (expectedCycleTime == 0){
        expectedCycleTime = now + interval;
    }
    else {
        adjustedInterval = interval - (now - expectedCycleTime);
        expectedCycleTime += interval;
    }

    // function calls itself after delay of adjustedInterval
    setTimeout(function () {
        runAtInterval();
    }, adjustedInterval);
}

在每次迭代中,该函数都会根据先前计算的预期时间检查实际执行时间,然后从“interval”中减去差异以产生“adjustedInterval”。这种差异可能是正的或负的,结果表明实际执行时间倾向于在“真实”值 +/- 5 毫秒附近波动。

无论哪种方式,如果你有一个每分钟执行一次的任务,并且你运行它一整天,使用这个函数你可以预期 - 一整天 - 每个小时都会发生 60 次迭代。你不会有那个偶然的小时,你只得到 59 个结果,因为最终一分钟已经过去了。

于 2018-11-16T01:06:43.183 回答
1

setInterval肯定是漂流(虽然我同意它应该)。我正在运行一个间隔为 30 秒的 Node.js 服务器。在每个滴答声中,都会发出一些异步 Web 请求,从开始到结束大约需要 1 秒。在中间的 29 秒内没有其他用户级/应用程序处理发生。

但是,我从我的服务器日志中注意到,在 30 分钟的过程中,发生了 100 毫秒的漂移。当然,漂移不能归咎于底层操作系统,它只能是 Node.js 的设计或实现的一些缺陷。

于 2016-02-29T19:19:17.077 回答
1

我很失望地注意到 setInterval 的 NodeJS 实现中有一个错误。请看这里:

https://github.com/nodejs/node/issues/7346#issuecomment-300432730

于 2017-05-10T13:47:48.210 回答
0

您可以使用 Date() 对象设置特定时间,然后在日期上添加一定的毫秒数。

于 2013-08-10T23:00:05.403 回答
0

由于 Javascript 的工作原理,它绝对可以(请参阅事件循环

Javascript 事件循环在其他排队事件完成时执行 setInterval 队列。这些事件将需要一些时间,并且会影响您的 setInterval 函数的执行时间,并且最终会随着时间的流逝而消失。

于 2017-05-10T13:53:11.877 回答
-1

setInterval 不应该在完美的世界中漂移。由于其他事情占用系统资源,它可能会延迟。如果您需要更精确的解决方案,请使用 clock() 函数来“校准”您的节点。

于 2013-08-10T22:58:24.690 回答