2009-06-15 17 views
12

moim problemem jest to, że nie mogę zatrzymać stopera.Zatrzymanie rozliczenia w funkcji rekurencyjnej

Miałem this method, aby ustawić limit czasu z tego forum. Ma przechowywać identyfikator w zmiennej globalnej. Przez przypadek dowiedziałem się, że nadal działa po tym, jak ukryłem "mydiv".

Muszę również wiedzieć teraz, czy funkcja rekursywna tworzy wiele instancji, czy tylko jeden dla limitów czasu. Ponieważ najpierw pomyślałem, że nadpisuje "var mytimer" za każdym razem. Teraz nie jestem tego taki pewien.

Jaki byłby solidny sposób, aby zatrzymać stoper?

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

dzięki Richard

Odpowiedz

7

Chyba nie zrozumiałeś 'setTimeout' i 'clearTimeout'.

foo = setTimeout(function, time); 

następnie zadzwonić

clearTimeout(foo); 

jeśli chcesz anulować to czasomierz:

Jeśli chcesz ustawić timer, który chcesz anulować później coś takiego zrobić.

Mam nadzieję, że to pomoże!

+0

powiedziałbym, że było całkiem źle - to funkcjonalne, ale nie ma sposobu, aby to anulować (ponieważ wartość setTimeout nie została przechwycona), ale jest to łatwe i nieskomplikowane w porównaniu do żądania co sekundę. To naprawdę przesadne, imho. – annakata

+0

dziękuję, teraz nie rozumiem już mojego własnego kodu. Jaka jest korzyść z korzystania z tych anonimowych funkcji? Zobacz link –

+0

to zupełnie inne pytanie, ponieważ odpowiedź jest dość rozległa :) – annakata

2

Ponieważ napisany mytimer jest funkcją, która nigdy nie ma wartości identyfikatora limitu czasu, zatem instrukcja clearTimeout nic nie osiągnie.

nie widzę żadnej rekurencji tutaj w ogóle, ale trzeba przechowywać wartość setTimeout powrót, a jeśli trzeba powiązać to z wieloma potencjalnymi trzeba przechowywać go na wartość klucza możesz lookup - może coś w rodzaju elementu id?

+0

Rozumiem, co mówisz. –

0

Jak wspomniano wyżej, głównym powodem, dlaczego ten kod nie działa jest to, że jesteś passingt on źle rzeczą do rozmowy clearTimeout - trzeba przechowywać wartości zwracanej z setTimeout zadzwonić dokonać w updateFunction i przekazać to w clearTimeout, zamiast samego odwołania do funkcji.

Jako druga sugestia poprawy - zawsze, gdy masz funkcję rekurencyjnego limitu czasu, lepiej byłoby użyć metody setInterval, która uruchamia funkcję w regularnych odstępach czasu do momentu anulowania. Osiągniesz to samo, co próbujesz zrobić przy użyciu metody updateFunction, ale jest to czystsze, ponieważ musisz tylko uwzględnić logikę "do zrobienia" w funkcji odroczonej i prawdopodobnie jest bardziej wydajna, ponieważ nie będziesz tworzyć zagnieżdżonych zamknięcia. Plus to właściwa droga, która musi się liczyć, prawda? :-)

+0

Z dyskusji na http://stackoverflow.com/questions/729921/settimeout-or-setinterval, setInterval nie zawsze jest lepiej. – billyswong

+0

tak, z samej tej dyskusji wynika, że ​​ma ona tendencję do używania timeoutu jako preferowanej metody. ponieważ setinterval zgłosi się na przykład. Nie wiem o zagnieżdżonych zamknięciach. Może masz rację. –

20

Myślę, że większość ludzi zaczyna rozumieć, dlaczego to nie działa, ale myślałem, że dostarczę ci zaktualizowany kod. Jest prawie taki sam jak twój, z tym wyjątkiem, że przypisuje limit czasu do zmiennej, dzięki czemu można go wyczyścić.

Również anonimowa funkcja w setTimeout jest świetna, , jeśli chcesz uruchomić logikę inline, zmień wartość "this" w funkcji lub przeprowadź parametry do funkcji.Jeśli chcesz tylko wywołać funkcję, wystarczy podać nazwę funkcji jako pierwszy parametr.

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

(funkcja() {

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

     }) 

})();

+1

Czy możesz [edytować] i wyjaśnić, w jaki sposób odpowiada na pytanie? – yhw42

0

Nie można zatrzymać wszystkie funkcje, które są tworzone, intead które przekształcają funkcję setInterval (reprezentują tę samą logikę, która swoją rekurencyjna funkcja) i powstrzymać go:

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

tą samą logiką użyciu setInterval:

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

Zatrzymaj go:

clearInterval(timer); 
Powiązane problemy