我很难理解javascript中setTimer方法背后的逻辑。
<html><head>
<script>
function Timer () {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
document.getElementById('show').innerHTML=h+":"+m+":"+s;
t = setTimeout("Timer()", 1000);
}
</script>
</head>
<body onload="Timer()">
<div id="show"></div>
</body></html>
setTimeout用于延迟函数/方法执行。那为什么它被用在实时时钟?
t = setTimeout("Timer()", 1000);
这部分令人困惑。
答案 0 :(得分:2)
您的代码:
t = setTimeout("Timer()", 1000);
你应该知道的第一件事是将第一个参数放在一个字符串中被认为是不好的做法 - 它应该是函数名,不带引号,没有括号,如下所示:
t = setTimeout(Timer, 1000);
除此之外,你的问题是关于它用于显示时钟的原因:
在setTimeout()
函数中使用Timer()
来调用自身是一种常见的Javascript模式,可以重复调用函数。 setTimeout()
本身只会在给定的时间段过后触发一次调用的函数,因此对于重复事件,每次都需要重新触发。
由于setTimeout
调用位于Timer()
函数内,因此在第一次通过其他方式调用Timer()
之前不会设置它。这就是body onload
的用武之地。
正如您所怀疑的那样,setTimeout()
并不是一种确保在完全给定时间后调用函数的准确方法。 Javascript不是多线程的,因此任何触发的事件处理程序都必须等待同时运行的任何其他代码。如果其他东西运行缓慢,这可能导致您的计时器不会在它想要的那一刻被触发。
但是,对于您的时钟来说,这不是一个真正的问题,因为时钟将自己设置为实际的系统时间,而不是依靠setTimeout
循环来保持自身同步; setTimeout
循环只是用于确保显示每秒更新一次(大约)。如果它实际上不是每秒一次,那真的不重要。
我希望这有助于更好地解释事情。
答案 1 :(得分:2)
在经过一段时间后,时钟以递归方式调用自身。
在JS中制作实时时钟是不可能的。
由于JS引擎的工作原理,如果你将Timer
置于一个循环中,要运行一段无限的时间,你就永远不会在屏幕上看到时间更新(因为更改不会被绘制到窗口,直到一个函数完成,程序中有一个空白)。
此外,在无限循环内部,不可能对页面做任何其他事情(甚至关闭它),因为JS一次只能做一件事,所以它不能听任何用户的点击,直到它的完成这个循环.......
这就是setTimeout
的用途。
Timer
是充当时钟的函数。
在Timer
函数内部,当所有工作完成时,它告诉setTimeout
等待1秒(1000毫秒)然后调用一个名为Timer
的函数。
Timer
恰好是同一个功能。但setTimeout
不知道,也不关心。
在这种情况下,t
基本上没用。 setTimeout
将返回一个数字 - 就像在医生办公室取一个号码一样。
如果在你完成它之前,你决定退出,你可以拨打clearTimeout(t);
并跳过该呼叫(在这种情况下,它会停止呼叫时钟)。
这里有一些不良做法,我想我应该提一下,这样你就可以尝试不在自己的实践中复制它们。
第一:
传递setTimeout
对函数的引用,而不是字符串......
var runThisFunction = function () { console.log("It's the future!"); },
time_to_wait = 250;
// DON'T DO THIS
setTimeout( "runThisFunction()", 250 );
// DO THIS
setTimeout( runThisFunction, 250 );
不同之处在于setTimeout
将通过eval
运行该字符串,这可能是一个巨大的安全问题,具体取决于您要执行的操作。
第二个问题是设置一个随机的全局变量t
......并希望将其用作解决方案。
首先,在几年内,JS引擎将开始大肆宣传这些东西。其次,这是一个巨大的漏洞,因为该页面上任何应用程序的任何部分都可以覆盖t
,或者您可能依赖于脚本中其他位置的t
,但每1000毫秒,它会被写入用一个新号码。
相反,他们可能应该使用Timer.start();
和Timer.stop();
设置。
答案 2 :(得分:0)
当调用Timer()
函数时,它会安排自己在一秒后再次运行。最终结果是每秒一次,Timer()
使用当前时间更新show
元素。 (我不知道为什么将它分配给t
,除非在页面上的其他代码中使用t
。)
答案 3 :(得分:0)
该行在一秒后再次启动该功能。