带有计时事件的 JavaScript 递归 (setTimeout)

Posted

技术标签:

【中文标题】带有计时事件的 JavaScript 递归 (setTimeout)【英文标题】:JavaScript Recursion with Timing Event (setTimeout) 【发布时间】:2012-01-31 15:41:28 【问题描述】:

我正在尝试使用 javascript 构建一个计时器。这是我的功能:

var t;
function time(num)
    var buf = num;
    document.getElementById("test").innerhtml=buf;
    buf++;
    alert(buf + " " + num); //For troubleshooting
    t=setTimeout("time(buf)",1000);

如果我运行 time(0),ID="test" 的部分不会发生任何事情。每次调用函数时,num 始终等于 0,buf 始终等于 1(来自警报函数)。

我对 Java 和 C 很熟悉,而且我知道这适用于这些语言。我知道 JavaScript 也是一种按值传递的语言,那么为什么这个计时器不起作用呢?

另外,为什么我尝试(并将所有buf更改为num)时没有任何反应

t=setTimeout("time(num)",1000);

我知道还有其他方法可以创建计时器,但我想知道为什么这种方法不起作用。谢谢。

【问题讨论】:

你可能认为这是递归,但实际上不是。 time() 被调用,然后它调用setTimeout() 并传递一个稍后将执行的字符串。然后,time() 返回,一段时间后,定时器代码再次调用time()。这在技术上不是递归。对time() 的第一次调用在第二次调用之前已经完成。您只是将第二次通话安排在未来一段时间。 【参考方案1】:

避免将字符串传递给setTimeout。当你这样做时,字符串或多或少地被执行为eval,这有很多原因是邪恶的。请参阅this question 了解更多信息。

请考虑将匿名函数传递给setTimeout。这将使解决您的问题变得微不足道:

t = setTimeout(function()  time(buf); , 1000);

【讨论】:

【参考方案2】:

当您将字符串传递给setTimeout 时,它会在时机成熟时进行评估。在这种情况下,到时候,没有buf变量了,代码会抛出错误。

您应该自己替换该值。

t = setTimeout("time(" + buf + ")",1000);

或者,更好的是,传递一个函数而不是字符串

t = setTimeout(function() 
  time(buf);
, 1000);

【讨论】:

以上是关于带有计时事件的 JavaScript 递归 (setTimeout)的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript 计时事件

JavaScript计时事件

JavaScript计时器

JavaScript 计时

javaScript 笔记 -- 弹窗 & 计时事件 & cookie

js の 计时器