Подтвердить что ты не робот

Stop setimeout в рекурсивной функции

моя проблема в том, что я не могу остановить таймер.

У меня был этот метод, чтобы установить тайм-аут с этого форума. Он должен хранить идентификатор в глобальной переменной. Случайно я узнал, что он все еще работает после того, как я скрою "mydiv".

Мне также нужно знать сейчас, если рекурсивная функция создает несколько экземпляров или только один для тайм-аутов. Потому что сначала я думал, что он каждый раз перезаписывает "var mytimer". Теперь я не уверен.

Что было бы надежным способом остановить таймер?

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();
               }
});

спасибо, Ричард

4b9b3361

Ответ 1

Я думаю, что большинство людей получают по этой причине, почему это не работает, но я думал, что дам вам обновленный код. Это почти то же самое, что и у вас, за исключением того, что он назначает время ожидания переменной, чтобы ее можно было очистить.

Кроме того, анонимная функция в setTimeout велика, если вы хотите запустить встроенную логику, измените значение 'this' внутри функции или передайте параметры в функцию. Если вы просто хотите вызвать функцию, достаточно передать имя функции в качестве первого параметра.

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();
   }
});

Ответ 2

Я думаю, вы неправильно поняли "setTimeout" и "clearTimeout".

Если вы хотите установить таймер, который вы хотите отменить позже, сделайте следующее:

foo = setTimeout(function, time);

затем вызовите

clearTimeout(foo);

если вы хотите отменить этот таймер.

Надеюсь, это поможет!

Ответ 3

Как написано mytimer - это функция, которая никогда не имеет значения идентификатора тайм-аута, поэтому ваш оператор clearTimeout ничего не добьется.

Я вообще не вижу рекурсии, но вам нужно сохранить значение setTimeout, и если вам нужно соединить это с несколькими потенциальными событиями, вам нужно сохранить его против ключевого значения, которое вы можете найти - что-то например, идентификатор элемента?

Ответ 4

Вы не можете остановить все созданные функции, чтобы преобразовать функцию в setInterval (указать ту же логику, что и ваша рекурсивная функция), и остановить ее:

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

Та же логика с использованием setInterval:

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

Остановить:

 clearInterval(timer);

Ответ 5

Как отмечалось выше, основная причина, почему этот код не работает, заключается в том, что вы передаете ему неправильную вещь в вызов clearTimeout - вам нужно сохранить возвращаемое значение вызова setTimeout, который вы делаете в updateFunction и передать это в clearTimeout вместо самой ссылки функции.

В качестве второго предложения для улучшения - всякий раз, когда у вас есть то, что вы называете рекурсивной функцией тайм-аута, вам лучше использовать метод setInterval, который выполняет функцию с регулярными интервалами до отмены. Это позволит достичь того же, что вы пытаетесь сделать с помощью метода updateFunction, но он более чист, поскольку вам нужно включить логику "делать что-то" в отложенной функции, и это, вероятно, более результативно, поскольку вы не будете создание вложенных замыканий. Плюс это правильный способ сделать это, который должен что-то посчитать, не так ли?: -)

Ответ 6

(функция() {

$('#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);

        })

})();

Ответ 7

Это простой псевдокод для управления и преобразования рекурсивных функций setTimeout.

    const myVar = setTimeout(function myIdentifier() {

    // some code

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

}, delay);