2009-07-26 16 views
51

Potrzebuję dodać opóźnienie około 100 milisekund dla mojego kodu JavaScript, ale nie chcę używać funkcjiobiektu window i nie chcę używać pętli zajęty. Czy ktoś ma jakieś sugestie?Umieścić opóźnienie w JavaScript

+15

Czy możesz wyjaśnić, dlaczego setTimeout nie jest właściwe/nie spełnia Twoich potrzeb? – eyelidlessness

Odpowiedz

110

Niestety setTimeout() jest jedynym niezawodny sposób (nie tylko w ten sposób, ale tylko niezawodny sposób), aby wstrzymać wykonanie skryptu bez blokowania UI.

To nie jest takie trudne do zastosowania w rzeczywistości, zamiast pisać to:

var x = 1; 

// Place mysterious code that blocks the thread for 100 ms. 

x = x * 3 + 2; 
var y = x/2; 

użyć setTimeout() przepisać to w ten sposób:

var x = 1; 
var y = null; // To keep under proper scope 

setTimeout(function() { 
    x = x * 3 + 2; 
    y = x/2; 
}, 100); 

Rozumiem, że za pomocą setTimeout() wymaga więcej myśli niż miało to miejsce pożądana funkcja sleep(), ale niestety późniejsza nie istnieje. Istnieje wiele sposobów na rozwiązanie takich funkcji. Niektóre używają zajętych pętli:

function sleep(milliseconds) { 
    var start = new Date().getTime(); 
    for (var i = 0; i < 1e7; i++) { 
    if ((new Date().getTime() - start) > milliseconds){ 
     break; 
    } 
    } 
} 

inne using an XMLHttpRequest tied with a server script that sleeps for a amount of time before returning a result.

Niestety, są to rozwiązania, które mogą powodować inne problemy (np. Zamrażanie przeglądarek). Zaleca się po prostu trzymać w zalecany sposób, czyli setTimeout()).

+2

Używam NoScript na moim laptopie właśnie dlatego, że ludzie używają funkcji takich jak funkcja snu lub innych bezsensownych ciasnych pętli. W przeciwnym razie nagle spala dziurę na kolanach. –

+3

** @ James M.:** Całkowicie Zgadzam się ... Nigdy nie rozumiałem, dlaczego istnieje takie duże piętno wokół 'setTimeout()'. –

+2

Nie sądzę, że setTimeout() ma jakiekolwiek piętno, które go otacza, ponieważ nie zawsze daje łatwo pożądany efekt. Powiedz, na przykład, jeśli chcesz, aby procesor pracował na biegu jałowym przez krótki czas w pętli intensywnej, aby uniknąć zablokowania przeglądarki. Osiągnięcie tego wyniku za pomocą setTimeout może być trudne dla niedoświadczonych programistów JavaScript. – KingRadical

2

This thread ma dobre dyskusji i użyteczne rozwiązanie:

function pause(iMilliseconds) 
{ 
    var sDialogScript = 'window.setTimeout(function() { window.close(); }, ' + iMilliseconds + ');'; 
    window.showModalDialog('javascript:document.writeln ("<script>' + sDialogScript + '<' + '/script>")'); 
} 

Niestety okazuje się, że to nie działa w niektórych wersjach IE, ale wątek ma wiele innych godnych propozycji, jeżeli okaże się problem dla Ciebie.

+2

Wydaje się, że to rozwiązanie czeka na problem. Nie mogę myśleć o pojedynczej sytuacji, w której 'setTimeout' nie wykona swojej pracy. Ale +1 za kreatywność. :) –

3

W rzeczywistości tylko setTimeout jest w porządku dla tego zadania i zwykle nie można ustawić dokładnych opóźnień z nieokreślonymi metodami jako pętli zajętych.

+0

Nie można zatrzymać interpretera JS za pomocą setTimeout. –

+0

Możesz wywołać funkcję tylko po pewnym czasie. setTimeout nie "blokuje". Reszta kodu działa tak, jak powinna. –

11

Po prostu miałem problem, który musiał rozwiązać.

Za pośrednictwem Ajax skrypt otrzymuje komunikaty X (0-10). Co chciałem zrobić: Dodaj jedną wiadomość do DOM co 10 sekund.

kod I skończył z:

$.each(messages, function(idx, el){ 
    window.setTimeout(function(){ 
    doSomething(el); 
    },Math.floor(idx+1)*10000); 
}); 

zasadzie myśleć o limity czasu jako „osi czasu” skryptu.

To co chcemy kodu:

DoSomething(); 
WaitAndDoNothing(5000); 
DoSomethingOther(); 
WaitAndDoNothing(5000); 
DoEvenMore(); 

ten sposób musimy poinformować go do javascript:

At Runtime 0 : DoSomething(); 
At Runtime 5000 : DoSomethingOther(); 
At Runtime 10000: DoEvenMore(); 

nadzieję, że to pomaga.

+0

Dziękujemy za odpowiedź wyjaśniającą zachowanie SetTimeOut. Problem polega na tym, że później, gdy kod jest długi lub zależy od odpowiedzi serwera, trudno jest nawet wizualizować rzeczywistą oś czasu w kilka sekund. –

-5

Użyj funkcji AJAX, która będzie synchronicznie wywoływała stronę php, a następnie na tej stronie możesz umieścić funkcję php usleep(), która będzie działać jako opóźnienie.

function delay(t){ 

var xmlhttp; 

if (window.XMLHttpRequest) 

{// code for IE7+, Firefox, Chrome, Opera, Safari 

xmlhttp=new XMLHttpRequest(); 

} 

else 

{// code for IE6, IE5 

xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); 

} 

xmlhttp.open("POST","http://www.hklabs.org/files/delay.php?time="+t,false); 

//This will call the page named delay.php and the response will be sent to a division with ID as "response" 

xmlhttp.send(); 

document.getElementById("response").innerHTML=xmlhttp.responseText; 

} 

http://www.hklabs.org/articles/put-delay-in-javascript

+4

proszę sformatować kod, aby był czytelny. – kleopatra

+9

Nie zapomnij o podstawach projektowania stron internetowych. Podstawową zasadą jest zmniejszenie obciążenia serwera tak bardzo jak to tylko możliwe. Dla prostego opóźnienia czasowego żądasz nieskończonej liczby stron z serwera. Pomyśl o tym, co tutaj robisz. –

Powiązane problemy