可能用过这个函数的兄弟们都知道,alertTimeout函数的执行结果是无限循环,事实上stop函数本身并没有问题,如果该语句在这个回调过程外被执行,即单击一下页面中的按钮,是可以停止的。我只想知道为什么,是不是clearTimeout在本身的回调事件队列中就不起作用
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>timeout</title>  <script type="text/javascript">
      var iMove;
     
    function alertTimeout() {        if (iMove) {
            stop();
        }
        alert("something");
        iMove = window.setTimeout(alertTimeout, 1000);
        
    }    function stop() {clearTimeout(iMove); }    window.onload = function() {
        alertTimeout();
    }
  </script>
</head>
<body>
<input type="button" onclick="stop();" />
</body>
</html>

解决方案 »

  1.   

    个人理解:
    setTimeout时,设置了1个定时器,iMove保存这个定时器的编号,到时间后只执行1次。
    到运行到alertTimeout时,这个编号的定时器已经不会再次执行了,所以clearTimeout就没什么意义了。
    clearTimeout清除指定编号的定时器。
    然后再次setTimeout,又生成了一个新的定时器,iMove保存新的定时器编号。LZ可以在setTimeout前后输出下iMove的值看一下。
      

  2.   

    是这样。当设置setTimeout后,会产生一个计时器编号句柄。当setTimeout到时间发生时,这个句柄就被清空了。因为setTimeout只执行一次,过后不再发生,自然发生后不会再保存句柄,否则就出错了。这和setInterval不同。楼主这样,在setTimeout的函数里面判断if(iMove),结果总是无值产生的假。所以应改为其它的计数变量才行。
      

  3.   

    感谢楼上的两位朋友
    不过二楼的朋友可以没注意,iMove是全局变量
    我们即使不用作实验也可以知道,iMove第一次是undefined,第二次是则是一个计时器编号int值
    这个if(iMove),事实上并非二楼朋友说的false,这个判断每次都是走得进去的,如果在判断内输出iMove,是看得到一个int值的
      

  4.   

    每一次进到function stop() {clearTimeout(iMove); }里的时候iMove都是一个过时的值 对其clearTimeout无意义 所以没有效果
      

  5.   

    alertTimeout
    iMove  undefined
    无需stop
    启一个线程 把id赋给iMove 
    过一秒
    alertTimeout 
    iMove过时
    stop无效
    启一个线程 把id赋给iMove 
    过一秒
    ....
    如此反复