2009-06-15 16 views
12

il mio problema è che non riesco a fermare un timer.stop settimeout in funzione ricorsiva

Avevo this method per impostare un timeout da questo forum. Si supponeva di memorizzare l'identificatore nella variabile globale. Per caso, ho scoperto che è ancora in esecuzione dopo aver nascosto "mydiv".

Ho anche bisogno di sapere ora, se la funzione ricorsiva crea più istanze o solo una per i timeout. Perché prima pensavo che sovrascrisse "var mytimer" ogni volta. Ora non ne sono così sicuro.

Quale sarebbe un modo solido per fermare il 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(); 
       } 
}); 

grazie, Richard

risposta

7

penso che frainteso 'setTimeout' e 'clearTimeout'.

Se si desidera impostare un timer che si desidera annullare in seguito, fare qualcosa di simile:

foo = setTimeout(function, time); 

quindi chiamare

clearTimeout(foo); 

se si desidera annullare quel timer.

Spero che questo aiuti!

+0

direi che era piuttosto male - è funzionale, ma non c'è modo di cancellarlo (perché il valore di setTimeout non viene catturato), ma è facilmente riparato e banale rispetto a fare una richiesta ogni secondo. È davvero eccessivo, imho. – annakata

+0

grazie, ora non capisco più il mio codice. Qual è il vantaggio di usare quelle funzioni anonime in ogni caso ??? vedi il link –

+0

che è tutta un'altra domanda perché la risposta è piuttosto ampia :) – annakata

2

Come mytimer scritto è una funzione che non ha mai il valore di un identificatore di timeout, pertanto l'istruzione clearTimeout non otterrà alcun risultato.

non vedo alcun ricorsione qui a tutti, ma è necessario memorizzare il valore di setTimeout si ritorna, e se è necessario associare questo con molteplici potenziali eventi è necessario memorizzare contro un valore chiave è possibile ricerca - qualcosa come un elemento id forse?

+0

Capisco cosa stai dicendo. –

0

Come notato sopra, il motivo principale per cui questo codice non funziona è che sei passingt lui cosa sbagliata nella chiamata clearTimeout - è necessario memorizzare il valore di ritorno del setTimeout vi invito a fare updateFunction e passare questo in clearTimeout, invece del riferimento alla funzione stessa.

Come secondo suggerimento per il miglioramento - ogni volta che si dispone di quella che si chiama una funzione di timeout ricorsivo, sarebbe meglio utilizzare il metodo setInterval, che esegue una funzione a intervalli regolari fino all'annullamento. Ciò otterrà la stessa cosa che stai cercando di fare con il tuo metodo updateFunction, ma è più pulito in quanto devi solo includere la logica "do stuff" nella funzione posticipata ed è probabilmente più performante dato che non creerai nidificazioni chiusure. Inoltre è il modo giusto per farlo che deve contare qualcosa, giusto? :-)

+0

Dalla discussione su http://stackoverflow.com/questions/729921/settimeout-or-setinterval, setInterval non è sempre migliore. – billyswong

+0

sì, da quella discussione da sola, si ottiene la nozione che tende ad usare il timeout come metodo preferito. perché setinterval quees up per esempio. Non so chiusure annidate. Forse hai ragione su questo. –

20

Penso che molte persone capiscano il motivo per cui questo non funziona, ma ho pensato di fornire un codice aggiornato. È praticamente uguale al tuo, tranne per il fatto che assegna il timeout a una variabile in modo che possa essere cancellata.

Inoltre, la funzione anonima in un setTimeout è grande, se si desidera eseguire la logica in linea, modificare il valore di 'questo' all'interno della funzione, o passare i parametri in una funzione.Se si desidera semplicemente chiamare una funzione, è sufficiente passare il nome della funzione come primo parametro.

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

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

     }) 

})();

+1

Puoi [modificare] e spiegare come questo risponde alla domanda? – yhw42

0

Non è possibile interrompere tutte le funzioni che vengono creati, intead di quella di convertire la funzione setInterval (rappresentare la stessa logica che la funzione ricorsiva) e fermarlo:

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

La stessa logica si utilizza setInterval:

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

stop it:

clearInterval(timer);