2012-10-21 24 views
5

Szukałem, jak używać setTimeOut dla pętli, ale nie ma zbyt wiele, jak używać go z pętlami, i nie widzę powodu, dla którego i tak powinna być duża różnica. Napisałem kilka odmian tego kodu, ale ta pętla wydaje się zawieszać przeglądarkę:setTimeout inside while loop

while(src == '') 
{ 
    (function(){ 
     setTimeout(function(){ 
     src = $('#currentImage').val(); 
     $("#img_"+imgIdx).attr('src',src); 
     }, 500); 
    }); 
} 

Dlaczego?

Zasadniczo mam obraz utworzony dynamicznie, którego atrybut źródłowy wymaga czasu, aby załadować, dlatego zanim będę mógł go wyświetlić, muszę sprawdzić, czy jest on załadowany czy nie, i tylko wtedy, gdy jego ścieżka jest dostępna w $('#currentImage'), to pokażę to.

Ten kod przepracowanych grzywny przed użyłem pętli while, a kiedy bezpośrednio nie

setTimeout(function(){ 
    src = $('#currentImage').val(); 
    $("#img_"+imgIdx).attr('src',src); 
}, 3000); 

Ale nie chcę mieć, aby użytkownik odczekać 3 sekundy, jeśli ładowanie można zrobić szybciej, dlatego wstawiam setTimeOut w pętlę while i zwinęłem jej interwał, tak że sprawdzam tylko załadowaną ścieżkę co pół sekundy. Co z tym jest nie tak?

+0

Nie, settimeout przyjmuje funkcję jako parametr i wykonuje ją później. – jrdn

+0

@jrdn Nie mówię o tym wewnątrz 'setTimeout', mówię o tym na zewnątrz. BTW, że deklaracja funkcji nie jest faktycznie potrzebna. –

+0

Ah. To też. Więc tak, moja odpowiedź jest błędna. To zwykła stara nieskończona pętla! – jrdn

Odpowiedz

3

Dzięki wszystkim - wszystkie sugestie pomogły. Na koniec użyłem setInterval w następujący sposób:

var timer; 
// code generating dynamic image index and doing ajax, etc 
var checker = function() { 
    var src = $('#currentImage').val(); 
    if(src !== '') { 
    $('#img_' + imgIdx).attr('src', src); 
     clearInterval(timer); 
    } 
}; 

timer = setInterval(checker, 500); 
+0

Potwierdź, że ten interwał został faktycznie wyczyszczony. ['window.clearInterval'] (https://developer.mozilla.org/en-US/docs/DOM/window.clearInterval) przyjmuje argument" intervalID "jako argument, a nie _funkcja_. –

+0

Też tak pomyślałem ... ale to działa. Najpierw zobaczyłem to w drugiej odpowiedzi tutaj: http://stackoverflow.com/questions/109086/stop-setinterval-call-in-javascript – user961627

+0

'i = 0; var fn = function() { console.log (++ i); jeśli (i> 9) console.log ('clearing'), clearInterval (fn); }; setInterval (fn, 500); 'trwa wiecznie. –

5

Problem polega prawdopodobnie na tym, że nie sprawdzasz co pół sekundy.

setTimeout planuje uruchomienie funkcji w przyszłości, ale nie blokuje, działa tylko później. Tak więc w pętli while planujesz te funkcje tak szybko, jak tylko mogą przerabiać pętlę while, więc prawdopodobnie tworzysz ich masę.

Jeśli rzeczywiście chcesz sprawdzić co pół sekundy, użyj setInterval bez pętli.

+0

setInterval zwraca identyfikator. Jeśli chcesz go zatrzymać, użyj clearInterval (id); – jrdn

+0

https://developer.mozilla.org/en-US/docs/DOM/window.clearInterval – jrdn

+0

Dzięki za wyjaśnienie. Biorę wtedy te bloki setInterval? – user961627

9

Pętla while powoduje problemy, na przykład wskazuje jrdn. Być może możesz połączyć zarówno setInterval, jak i setTimeout i po wypełnieniu src, wyczyść przedział. Umieściłem tu niektóre kod przykładowy, aby pomóc, ale nie jestem pewien, czy to całkowicie wpisuje swój cel:

var src = ''; 
    var intervalId = window.setInterval(
     function() { 

      if (src == '') { 
       setTimeout(function() { 
        //src = $('#currentImage').val(); 
        //$("#img_" + imgIdx).attr('src', src); 
        src = 'filled'; 
        console.log('Changing source...'); 
        clearInterval(intervalId); 
       }, 500); 
      } 
      console.log('on interval...'); 
     }, 100); 

    console.log('stopped checking.'); 

nadzieję, że to pomaga.