简体   繁体   English

在递归函数中停止settimeout

[英]stop settimeout in recursive function

my problem is that I can not stop a timer. 我的问题是我无法停止计时器。

I had this method to set a timeout from this forum. 我有这个方法来设置这个论坛的超时。 It supposed to store the identifyer in the global variable. 它应该将标识符存储在全局变量中。 By accident, I found out that it is still running after I hide "mydiv". 我意外地发现,在我隐藏“mydiv”之后它仍在运行。

I also need to know now, if the recursive function creates multiple instances or just one for the timeouts. 我现在还需要知道,如果递归函数创建多个实例,或者仅为超时创建一个实例。 Because first I thought that it overwrites "var mytimer" everytime. 因为首先我认为它每次都会覆盖“var mytimer”。 Now I am not so sure. 现在我不太确定。

What would be a solid way to stop the timer?? 什么是一个可靠的方法来停止计时器?

var updatetimer= function () {
//do stuff
        setTimeout(function (){updatetimer();}, 10000);

}//end function


//this should start and stop the timer
$("#mybutton").click(function(e) { 
         e.preventDefault();
         if($('#mydiv').is(':visible')){
                   $('#mydiv').fadeOut('normal');
             clearTimeout(updatetimer);

        }else{
                   $('#mydiv').fadeIn('normal');
                   updatetimer();
               }
});

thanks, Richard 谢谢,理查德

I think that most people are getting at the reason why this isn't working, but I thought I would provide you with updated code. 我认为大多数人都在理解为什么这不起作用,但我想我会为你提供更新的代码。 It is pretty much the same as yours, except that it assigns the timeout to a variable so that it can be cleared. 它与您的几乎完全相同,只是它将超时分配给变量以便可以清除它。

Also, the anonymous function in a setTimeout is great, if you want to run logic inline, change the value of 'this' inside the function, or pass parameters into a function . 此外,setTimeout中的匿名函数很棒, 如果要运行逻辑内联,更改函数内部的'this'值,或将参数传递给函数 If you just want to call a function, it is sufficient to pass the name of the function as the first parameter. 如果您只想调用一个函数,只需将函数名称作为第一个参数传递即可。

var timer = null; 

var updatetimer = function () {
    //do stuff

    // By the way, can just pass in the function name instead of an anonymous
    // function unless if you want to pass parameters or change the value of 'this'
    timer = setTimeout(updatetimer, 10000);
};

//this should start and stop the timer
$("#mybutton").click(function(e) { 
     e.preventDefault();
     if($('#mydiv').is(':visible')){
        $('#mydiv').fadeOut('normal');
        clearTimeout(timer);  // Since the timeout is assigned to a variable, we can successfully clear it now

    } else{
        $('#mydiv').fadeIn('normal');
        updatetimer();
   }
});

I think you misunderstand 'setTimeout' and 'clearTimeout'. 我认为你误解了'setTimeout'和'clearTimeout'。

If you want to set a timer that you want to cancel later, do something like: 如果要设置要在以后取消的计时器,请执行以下操作:

foo = setTimeout(function, time);

then call 然后打电话

clearTimeout(foo);

if you want to cancel that timer. 如果你想取消那个计时器。

Hope this helps! 希望这可以帮助!

As written mytimer is a function which never has the value of a timeout identifier, therefore your clearTimeout statement will achieve nothing. 由于编写的mytimer是一个永远不具有超时标识符值的函数,因此您的clearTimeout语句将无法实现。

I don't see any recursion here at all, but you need to store the value setTimeout returns you, and if you need to pair this with multiple potential events you need to store it against a key value you can lookup - something like an element id perhaps? 我根本没有看到任何递归,但你需要存储值setTimeout返回给你,如果你需要将它与多个潜在事件配对,你需要将它存储在一个你可以查找的键值上 - 就像一个元素或许也许?

You can not stop all the functions that are created, intead of that convert the function to setInterval (represent the same logic that your recursive function) and stop it: 你不能停止所有创建的函数,将函数转换为setInterval(表示与递归函数相同的逻辑)并将其停止:

// recursive
var timer= function () {
// do stuff
  setTimeout(function (){timer();}, 10000);
}

The same logic using setInterval: 使用setInterval的相同逻辑:

 // same logic executing stuff in 10 seconds loop
 var timer = setInterval(function(){// do stuff}, 10000)

Stop it: 停下来:

 clearInterval(timer);

This is a simple pseudocode for controlling and conditioning recursive setTimeout functions. 这是一个简单的伪代码,用于控制和调节递归的setTimeout函数。

    const myVar = setTimeout(function myIdentifier() {

    // some code

    if (condition) {
        clearTimeout(myIdentifier)
    } else {
        setTimeout(myIdentifier, delay); //delay is a value in ms.
    }

}, delay);

(function(){ (功能(){

$('#my_div').css('background-color', 'red');
$('#my_div').hover(function(){
var id=setTimeout(function() {
    $('#my_div').css('background-color', 'green');
}, 2000);

var id=setTimeout(function() {
    $('#my_div').css('background-color', 'blue');
}, 4000);
var id=setTimeout(function() {
    $('#my_div').css('background-color', 'pink');
}, 6000);

    })

$("#my_div").click(function(){  
        clearTimeout(id);

        })

})(); })();

As noted above, the main reason why this code isn't working is that you're passingt he wrong thing into the clearTimeout call - you need to store the return value of the setTimeout call you make in updateFunction and pass this into clearTimeout, instead of the function reference itself. 正如上面提到的,为什么这个代码不工作的主要原因是,你passingt他做错事到clearTimeout调用-你需要存储的返回值setTimeout叫你做updateFunction并通入clearTimeout 这一点 ,而不是函数引用本身。

As a second suggestion for improvement - whenever you have what you call a recursive timeout function, you would be better off using the setInterval method, which runs a function at regular intervals until cancelled. 作为改进的第二个建议 - 只要你有一个你称之为递归超时函数的东西,你最好使用setInterval方法,该方法定期运行一个函数直到被取消。 This will achieve the same thing you're trying to do with your updateFunction method, but it's cleaner as you only need to include the "do stuff" logic in the deferred function, and it's probably more performant as you won't be creating nested closures. 这将实现与您尝试使用updateFunction方法相同的功能,但它更干净,因为您只需要在延迟函数中包含“do stuff”逻辑,并且它可能更updateFunction ,因为您不会创建嵌套关闭。 Plus it's The Right way to do it which has got to count for something, right? 加上它是正确的做法,它必须要有所作为,对吗? :-) :-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM