我正在大型应用程序的前端实现实时时钟。为此,我想出了以下方法-
JavaScript
var span = document.getElementById('span');
function time() {
var d = new Date();
var s = d.getSeconds();
var m = d.getMinutes();
var h = d.getHours();
span.textContent = h + ":" + m + ":" + s;
}
setInterval(time, 1000);
HTML
<span id="span"></span>
这种方法可以很好地隔离工作,但是当将此代码集成到具有多个事件和函数调用的应用程序中时,时钟会在几小时后开始延迟几分钟,直到刷新页面为止。
我认为此延迟是由于setInterval
是一个Web(浏览器)API,并且是异步处理的,如果每次调用后堆栈都不为空,则它可能无法在每次编写代码的1秒后准确执行由于事件循环的调用堆栈中存在其他函数调用/事件,因此setInterval
被记录了1秒。
因此,如果长时间不刷新页面,则延迟会继续增长。该应用程序也是用Angular编写的,它是一个单页应用程序,在该页面中,由于进行路由,直到强制刷新页面后,该页面才会在导航时重新加载。
那么,如何在JavaScript中构建一个精确的时钟,将其集成到大型应用程序中却永不延迟?
更新:谢谢大家的答复。我认为你们中的某些人是正确的,我可能会遗漏一些细节。实际上,这几天我是在上班时实施的,但是由于某种原因不得不离开,并失去了对它的了解。但是肯定要使用Date
和Timers
时存在一些延迟问题。现在突然想到了这个,想到在这里问。非常抱歉,没有提供具体细节。
仍然,我将尝试重新收集详细信息,并在可能的情况下相应地更新问题。
答案 0 :(得分:2)
几个小时后,时钟开始延迟几分钟,直到页面刷新。
对于您所显示的代码来说,这是不可能的,无论您多久将其值反映到页面上,new Date
都应该返回正确的时间。
因此,如果长时间不刷新页面,则延迟会继续增长。
当今大多数浏览器都会略微调整计时器,以使其平均准确(例如,如果一个计时器延迟调用1毫秒,下一个计时器延迟调用1毫秒),那么您只能在如果您要离开页面的时间较长,则会暂停计时器。但这仍然不应该影响new Date
。
答案 1 :(得分:1)
当页面没有焦点时,Web浏览器中的计时器会回拨。您不能更改或阻止。您已经已经做着重要的主要事情:使用 current 时间更新时钟,从而即使不调用time
函数三秒钟时,它将以当前时间更新,跳过中间值。 (您经常看到人们认为计时器将以1000ms的间隔运行,而只是增加秒数而不是使用当前时间,这是不正确的。)
如果我这样做的话,我可能会缩短间隔(更频繁地运行回调),并使用一系列setTimeout
而不是单个setInterval
的链式链接,这尤其是因为不同的浏览器具有历史上以不同的方式处理setInterval
。
例如:
function time() {
var d = new Date();
var s = d.getSeconds();
var m = d.getMinutes();
var h = d.getHours();
span.textContent = h + ":" + m + ":" + s;
setTimeout(time, 250);
}
time();
但是如果页面处于非活动状态,时钟将会过期,因为浏览器将完全暂停计时器的执行或至少明显地将其回拨。不过,当页面再次变为活动状态时,希望它在不超过250毫秒后会自行纠正。