2013-06-19 69 views
1

我不太清楚这个问题的机制,但我试图将一个setTimeout设置为一个变量ID,我可以使用clearTimeout轻松取消该变量ID。但是,如果setTimeout在clearTimeout之前被触发两次,事情就会变得古怪。取消多个超时设置为ID

例子: http://www.w3schools.com/js/tryit.asp?filename=tryjs_settimeout2

点击“实战”两次,然后“停止警报”两次,设定超时的功能仍然被调用。同样,我不确定为什么Try It会两次触发该函数,因为事件被保存到一个正在被覆盖的变量中。

想知道这里发生了什么?

+0

第二次调用'setTimeout()'时,对第一个定时器的引用会丢失,但它仍然存在(某处)并且会运行。当你点击“停止”时,只有第二个超时(只有你有一个引用)被禁用。如果你调用'setTimeout()'而不是首先将它存储在一个变量中,它基本上是一样的。 – MCL

+0

因此,根据这些知识,“解决”问题的一种方法是仅通过在调用之前清除Timeout的函数来调用setTimeout。它会每次重置定时器,只触发超时目标功能一次,但至少清除将正常工作。 [在此尝试。](http://jsbin.com/ecocol/2/) – dhelm

+0

或者您只是使用多个参考:多个变量或一个数组。 – MCL

回答

3

与MCL所解释的一样,您将丢失对之前超时的引用,因为新的分配将覆盖它。

你可以做的是把超时到一个数组:

这样你就可以点击Stop the alert按钮时取消最后一组超时。

现场演示jsFiddle

+0

换句话说,为了防止任何计时器开火,人们必须点击“停止”次数来点击“开始”。 – MCL

+0

完美。在这个和我上面链接的例子之间,我认为这涵盖了我可能需要的行为。谢谢! – dhelm

+0

@dhelm你很好。您也可以使用数组索引来取消特定顺序的超时,而不是只弹出最后一个超时。 – Teemu