【问题标题】:Javascript: Can't stop the setTimeoutJavascript:无法停止 setTimeout
【发布时间】:2010-01-13 22:00:18
【问题描述】:

我正在开发代理服务器检查器,并使用以下代码以大约 5 秒的间隔使用 setTimeout 函数启动请求;

        function check() {

            var url = document.getElementById('url').value;
            var proxys = document.getElementById('proxys').value.replace(/\n/g,',');

            var proxys = proxys.split(",");

            for (proxy in proxys) {

                var proxytimeout = proxy*5000;

                t = setTimeout(doRequest, proxytimeout, url, proxys[proxy]);

            }
        }

但是一旦他们开始我就无法阻止他们!

        function stopcheck() {

            clearTimeout(t);

        }

修复或更好的方法将更受欢迎。

感谢 Stack Overflow 社区!

【问题讨论】:

  • 你确定你真的调用了stopcheck()并检查你是否在全局范围内定义了t
  • 作为更新;该函数确实会停止最后的 settimeout。
  • Ben,您正在覆盖 t 引用。只有最后一个 setTimeout 会被 t 引用。
  • 该代码还有一些其他问题;我已经更新了我的答案,把他们叫出来。

标签: javascript for-loop settimeout


【解决方案1】:

您的代码有两个主要问题:

  1. t 每次超时都会被覆盖,每次迭代都会丢失对上一个超时的引用。
  2. t 可能不是全局变量,因此 stopcheck() 可能无法“看到”t

更新功能:

function check() {
    var url         = document.getElementById('url').value;
    var proxys      = document.getElementById('proxys').value.replace(/\n/g,',');
    var timeouts    = [];
    var index;
    var proxytimeout;

    proxys = proxys.split(",");
    for (index = 0; index < proxys.length; ++index) {
        proxytimeout                = index * 5000;
        timeouts[timeouts.length]   = setTimeout(
            doRequest, proxytimeout, url, proxys[index];
        );
    }

    return timeouts;
}

function stopcheck(timeouts) {
    for (var i = 0; i < timeouts.length; i++) {        
        clearTimeout(timeouts[i]);
    }
}

使用示例:

var timeouts = check();

// do some other stuff...

stopcheck(timeouts);

【讨论】:

  • t 一个全局变量,从他发布的代码中我们可以看出。它没有在任何一个函数中声明,这意味着它要么是全局声明的,要么不是。在后一种情况下,它将成为 window 的隐含属性(例如,隐含的全局,尽管它们是可怕的)。当然,您的方法比这更好。
【解决方案2】:

“不”在哪里被定义? 它在 for 循环中不断被重新定义,因此您将失去对每个超时句柄的跟踪...

你可以保留一个句柄数组:

var aTimeoutHandles = new Array();
var iCount = 0;
for (proxy in proxys) {

    var proxytimeout = proxy*5000;

    aTimeoutHandles[iCount++] = setTimeout(doRequest, proxytimeout, url, proxys[proxy]);

}

【讨论】:

  • 如果您要设置多个超时,则需要跟踪每个超时,您当前执行此操作的方式每个超时句柄都会在创建每个新计时器时遭到破坏。还要确保在两个函数都可以看到的范围内定义您的句柄数组。
  • 哦 - 你不能像那样创建多个超时吗?我敢肯定我以前在某个地方做过!回复:数组-当然-我只是在演示您可以将超时句柄存储在数组中。我想我应该提到变量的范围很重要......
  • @Cryo:您的评论对于 OP 的问题是正确的,但罗伯特的回答将句柄存储在一个数组中。
【解决方案3】:

首先在两个函数之外定义t。此外,您将在每次迭代 for 循环时覆盖 t。也许建立一个引用集合,然后为了阻止它们,你循环遍历每个引用并 clearTimeout

【讨论】:

    【解决方案4】:

    每次设置间隔时都会覆盖t。因此,您最终只会清除最后一组。

    【讨论】:

      【解决方案5】:

      看起来您设置了多个超时(每个代理一个),但试图将它们保存在同一个变量中。您可能需要在那里使用数组,而不是简单的变量。

      【讨论】:

        【解决方案6】:

        你有几个问题:

        1. 主要是在for 循环的每次迭代中覆盖t;您需要一组 ts 才能使您的结构正常工作。
        2. 您正在使用for..in 循环遍历数组的索引。这不是for..in 的用途(尽管有很多 人对此感到困惑;see this article)。 for..in 循环遍历对象的属性名称,而不是数组的索引,因此这种用法在非平凡的情况下会中断。只需使用老式的 for 循环即可。
        3. 您声明了两次proxys。这实际上是无害的,但是...
        4. 您根本没有声明 proxy(这不是无害的;它变成了一个隐含的全局变量)。

        我已经更新了 Jordan 的优秀答案中的代码来解决这些问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-06-05
          • 2011-04-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多