0

我很难理解 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);

这部分令人困惑。

4

4 回答 4

2

你的代码:

t = setTimeout("Timer()", 1000); 

您应该知道的第一件事是,将第一个参数放在字符串中被认为是不好的做法——它应该是函数名,不带引号,并且不带括号,如下所示:

t = setTimeout(Timer, 1000); 

除此之外,您关于为什么将其用于显示时钟的问题:

使用函数setTimeout()内部Timer()调用自身是一种常见的 Javascript 模式,用于获取重复调用的函数。setTimeout()在给定的时间段过去后,它本身只会触发一次调用该函数,因此对于重复事件,每次都需要重新触发。

由于setTimeout调用在函数内部,因此在第一次通过其他方式调用Timer()之前不会设置它。Timer()这就是body onload进来的地方。

正如您所怀疑的那样,setTimeout()这不是保证在给定时间后调用函数的准确方法。Javascript 不是多线程的,因此任何触发的事件处理程序都必须等待同时运行的任何其他代码。如果其他东西运行缓慢,这可能会导致您的计时器没有在它想要的确切时间被触发。

但是,这对您的时钟来说并不是真正的问题,因为时钟将自己设置为实际的系统时间,而不是依靠setTimeout循环来保持同步;该setTimeout循环仅用于确保显示(大约)每秒更新一次。如果它实际上不是每秒一次,那并不重要。

我希望这有助于更好地解释事情。

于 2012-09-16T07:44:52.370 回答
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 毫秒,它就会被一个新数字覆盖。

相反,他们可能应该使用 a Timer.start();and Timer.stop();setup。

于 2012-09-16T08:01:31.163 回答
0

调用该Timer()函数时,它会安排自己在一秒钟后再次运行。最终结果是每秒一次,用当前时间Timer()更新元素。show(我不知道为什么将它分配给t,除非t在页面上的其他代码中使用。)

于 2012-09-16T07:22:29.590 回答
0

该行在一秒钟后再次启动该功能。

于 2012-09-16T07:23:16.453 回答