我有2个node.js网络服务器。我在Web服务器中缓存数据。我根据系统时间同步缓存加载/清除。我已经完成了所有主机的时间同步。
现在我使用以下代码每隔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 ......
是否会发生,而不是10:15系统时间,setInterval会在10:20系统时执行,因为它应该在10:15清除缓存?
我不确定这是如何运作的。请说清楚。我希望我能很好地解释我的问题。
答案 0 :(得分:1)
setInterval
肯定会漂移(虽然我同意不应该)。我正在运行一个间隔为30秒的Node.js服务器。在每个刻度线上,会产生一些异步Web请求,从头到尾大约需要1秒钟。在29秒内没有其他用户级/应用程序处理。
但是,我从服务器日志中注意到,在30分钟的过程中,发生了100ms的漂移。当然,底层操作系统不应该归咎于漂移,它只能是Node.js设计或实现的一些缺陷。
答案 1 :(得分:1)
我很失望地注意到setInterval的NodeJS实现中存在一个错误。请看这里:
https://github.com/nodejs/node/issues/7346#issuecomment-300432730
答案 2 :(得分:0)
您可以使用Date()对象设置特定时间,然后在日期中添加一定的毫秒数。
答案 3 :(得分:0)
肯定可以因为Javascript的工作方式(See Event Loop)
当其他排队事件完成时,Javascript事件循环执行setInterval队列。这些事件需要一些时间,它会影响你的setInterval函数的执行时间,并且随着时间的推移最终会逐渐消失。
答案 4 :(得分:0)
我在这里参加聚会的时间可能要晚一些,但这就是我现在通过递归调用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);
}
在每次迭代中,该函数都会相对于先前计算的预期时间检查 actual 执行时间,然后从“ interval”中减去差值以产生“ adjustedInterval”。这种差异可能是正的也可能是负的,结果表明,实际执行时间倾向于在“真实”值+/-〜5ms左右波动。
无论哪种方式,如果您有一个每分钟执行一次的任务,并且将其运行一整天,那么使用此功能,您可以期望-在整天中,每个小时将有60次迭代发生。您不会有一个偶然的小时,只能得到59个结果,因为最终整整一分钟都消失了。
答案 5 :(得分:-1)
setInterval不应该漂移在一个完美的世界里。由于其他事情占用系统资源,它可能会延迟。如果您需要更精确的解决方案,请使用clock()函数"校准"你的节点。