Ustawianie opóźnień w skryptach Javy nie jest takie oczywiste…
Z języków programowania chciałoby się użyć funckji sleep(int miliseconds); która zatrzyma CPU na jakiś czas – wiadomo, że jest to nieeleganckie, ale skuteczne. Jednak w przypadku stron WWW przykładowa implementacja
function sleep(milliseconds) { var start = new Date().getTime(); while (true) if ((new Date().getTime() - start) > milliseconds) break; }
naprawdę zawiesza procesor – nie jest to znane z C# System.Threading.Thread.Sleep(100) – więc wskazujące, że zawieszamy wątek, ale zawieszamy cały interpreter JS co równoznaczen jest z tym, że aktualizacje DOM czy po prostu tego co widzi użytkownik są niewidoczne. Ponadto monolity takie jak Mozilla Firefox zawisną w całej okazałości, czym może zainteresować się Windows – w skrajnej konfiguracji sam ubije nieodpowiadający proces. Przykład:
document.write("1
"); sleep(1000); document.write("2
"); sleep(1000); document.write("3
"); sleep(1000); document.write("4
"); sleep(1000);
Wykonanie zawiesi wszystko i dumnie ukaże nam po ok. 4 sekundach 1-2-3-4, a nie po kolei tak jakbyśmy chcieli.
Przejdźmy do jedynego słusznego rozwiązania , tj. setTimeout
setTimeout(function() { coś(); }, 1000);
Wszystko pięknie, ale sposób w jaki to zostanie zinterpretowane jest zaskakujący jak na trochę prymitywny względem wysokopoziomowców JavaScript. Otóż setTimeout znaczy to co znaczyć powinno tj. „zarejestruj event/przerwwanie, że za tyle milisekund wywołasz coś();, ale bez czekania tych milisekund wykonaj kolejną linię kodu”, a nie „odczekaj i wykona coś(); dopiero wtedy następną linię”. Oznacza to, że kod
setTimeout(function() {document.write('1
'); }, 1000); setTimeout(function() {document.write('2
'); }, 1000); setTimeout(function() {document.write('3
'); }, 1000); setTimeout(function() {document.write('4
'); }, 1000);
odczeka sekundę i wypluje wszystko na raz!
Właściwe rozwiązanie to kolejne setTimeout’y większe od poprzednich:
setTimeout(function() {document.write('1
'); }, 1000); setTimeout(function() {document.write('2
'); }, 2000); setTimeout(function() {document.write('3
'); }, 3000); setTimeout(function() {document.write('4
'); }, 4000);