Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Использование таймера (https://javascript.ru/forum/events/1034-ispolzovanie-tajjmera.html)

Strimer 09.02.2008 08:22

Использование таймера
 
Задача: реализовать отображение отсчета времени до закрытия окна.

Для реализации использую вот такие функции:
function Repl(ch)
{
var str = document.getElementById('ans').value;
str = str.replace(ch+1,ch);
document.getElementById('ans').value= str;
}

function CloseWindowTimer()
{
setTimeout("Repl(2);", 1000);
setTimeout("Repl(1);", 1000);
setTimeout("Repl(0);", 1000);
setTimeout("window.close();", 500);
}

на форме лежит <INPUT TYPE=submit name='ans' id='ans' VALUE='closing for 3 sec...'>

по зажумке на кнопке должен идти отсчет: 3сек... 2сек.. 1сек... 0сек... <полсекунды и закрытие>

на самом деле отсчет 3-2-1-0 происходит за один раз (2сек и 1сек зрительно не видно) и окно закрывается. В чем проблема? Такое ощущение, что setTimeoutы отрабатываются одновременно - почему?
(браузер Opera, IE7)

Dmitry A. Soshnikov 25.02.2008 14:21

Цитата:

Сообщение от Strimer
Такое ощущение, что setTimeoutы отрабатываются одновременно - почему?

потому что Вы их запускаете "одновременно", все они отработают через одну секунду (кроме последнего, который должен через полсекунды, т.е. раньше еще). setTimeout / setInterval работают с "отложенным временем", т.е. в Вашем примере абсолютно не значит, что setTimeout("Repl(1);", 1000); сработает через секунду после первого, а наоборот - все три - через секунду. Операции, идущие после setInterval'a будут продолжаться. Через секунду тред приостанавливается и "вклиниваются" три тайм-аута. В FF есть скрытый параметр задержки тайм-аутов (и интервалов), который, возможно, приводит к нужному результату (ну раз проблема только в Опере и IE), хотя, вряд ли.

Андрей Параничев 26.02.2008 23:12

Как сказал ds [.code], setTimeout создает ответвление от основного выполнения программы, так что в этом коде, по сути, не выполняется Repl(), т.к window.close() срабатывает на полсекунды раньше первого Repl().
К сожалению, в javascript нет реализаций функций остановки выполнения основной программы, по типу sleep или wait.

Как решение, можно запускать эту функцию в setInterval и считать кол-во вызовов, либо разницу во времени.

Dmitry A. Soshnikov 27.02.2008 00:50

Андрей Параничев,

Цитата:

Сообщение от Андрей Параничев
К сожалению, в javascript нет реализаций функций остановки выполнения основной программы, по типу sleep или wait.

на самом деле, сожаления нет =) иначе браузер бы повис - JavaScript однотредный язык (хотя, setTimeout и setInterval можно вынести во мнимый второй тред (первый прорисовывает окно, второй работает с "отложеным временем"), но в реале происходит лишь "вклинивание" в основной поток по истечению интервала).

Если Вас интересует синхронный дилэй с подвешиванием браузера (как например, модальное окно alert(...)), то можно использовать разницу миллисекунд объекта Date.

Андрей Параничев 27.02.2008 02:07

ds [.code],
Кстати да, я совсем не подумал об этом. Действительно ведь setTimeout и setInterval не являются в полной мере тредами. Точнее они совсем ими не являются, получается, если какую-нибудь функцию поставить на тайм-аут, то когда пройдет время тайм-аута функция всё-равно будет выполнятся в основной программе (прервав её выполнение)?

Dmitry A. Soshnikov 29.02.2008 13:29

странно, или форум гюканул или кто-то удалил мой пост (я уже отвечал на этот вопрос)

Цитата:

Сообщение от Андрей Параничев
получается, если какую-нибудь функцию поставить на тайм-аут, то когда пройдет время тайм-аута функция всё-равно будет выполнятся в основной программе (прервав её выполнение)?

да, именно так. Были реализации псевдо мультипоточности в JS (а с версии JS 1.7. и c ее yield, generator, iterator и прочими - еще легче, например - Threading in JavaScript 1.7 + демо), но все они, псевдо, т.к. JS - однотредный язык.

Андрей Параничев 29.02.2008 13:33

Да, я тоже удивился. Я тогда прочитал твой ответ, а потом он куда то пропал :)

Хералекс 07.09.2008 01:22

А у нас вроде как мультипочность наблюдаеться...
 
Ну вообщем фиг знает какой он там псевдо (кстати что вы имеете в виду этим словом) или не псевдомультипоточный на третьей лисе и вроде даже на iE6 замечательно идут и главная и куча параллельных функций одновременно.

P.S. Я сам сразу не вьехал что setTimeOut это не спящая функция =)


Часовой пояс GMT +3, время: 07:59.