k001
k001
:...
k001 [userpic]
javascript

Как это так случилось, что в JavaScript нет операции типа sleep, ну то есть чтобы сделать задержку. Там есть setTimeout(), который запустит указанную функцию через указанное время, но вот чтобы приостановить выполнение основного треда — я не нашёл.

Или я тупой?

Посчитать до 10000 не предлагайте, пожалуйста.

Update: вот такое нашёл, кажется, работает, во всяком случае в Thunderbird'е.

function sleep(millis) {
        var notifier = new EventNotifier();
        setTimeout(notifier, millis);
        notifier.wait->();
}    


Update2: ан нет, не работает нифига.

Comments

Насколько я это понимаю. Мозилла, из которой JS родом, не может параллельно с его исполнением делать что-либо ещё. Соответственно, sleep(10000) повесила бы на 10 секунд весь браузер.

Всё просто - JavaScript однопоточный. В новом (2.0) может и будет что-то такое, но до него и далеко и не просто...

Как это однопоточный? А setTimeout функцию разве не вторым потоком запускает?

В том-то и дело, что никакого потока не запускается :) просто какой-то код откладывается для выполнения

что-то совсем не похоже на однопоточность. Во всяком случае, в мозилле. Опыт показывает, что коллбэк на setTimeout вызывается много раз одновременно, несмотря на то, что n коллбэков уже блокируются на одной строчке.

Главное что с точки зрения программиста на JS потоков нет.
Кажется, их планируют ввести.

Ну, если нет настоящих потоков, то есть какая-то их эмуляция. Что с точки зрения программиста сравнимо по количеству создаваемого геморроя. Да и sleep можно было бы сделать.

Нет там ни многопоточности ни эмуляции - только один кусок кода исполняется пока не закончит исполнение, просто браузер сам многопоточный и там происходит много параллельных процессы отчего вся эта байда и усложняется, особенно в случаях XHR или простого и невозможно знать когда реально код или данные придут и тот или иной event handler будет запущен.

В JS2 обещают многопоточность, но на сколько это улучшит ситуацию с пониманием людей что к чему понять сложно и как будет сделано чтобы многопоточность не ломала текущие приложения я не знаю, единственное что меня успокаивает, это то что в за этим процессом активно следит Douglas Crockford и он не даст им допустить серьезных ошибок ;)

кусок кода != одна функция, вот в чём засада.

Позвольте, а как же асинхронное выполнение AJAX вызовов? с чем только вчера бился...

Удивляет, как много людей незнакомы с циклом обработки событий, типичным для любого GUI-приложения.

Стандартный цикл обработки событий, типичный для любого GUI-приложения, подразумевает, что пока не закончит своё выполнение один из коллбэков, ни один другой коллбэк не будет вызван(не считая вызовов, явно сделанных в первом коллбэке, само собой). Что в данном случае не имеет места быть.

Во первых, в обычных GUI, это не так и никаких проблем с вызовом параллельных потоков там нету.

В текущих браузерах же все совсем не так как вы говорите или я не прав и тогда попрошу вас показать мне какой-нибудь хороший пример обратного.

   <script> 
       function onMouseOver() 
       { 
           var child = document.createElement('div'); 
           child.innerHTML = "Loading..."; 
           document.body.appendChild(child); 
           ............................. 
           block(); 
           ............................. 
           document.body.removeChild(child); 
       } 
   </script> 
   
   <img src='some_img.gif' onmouseover='onMouseOver()'> 


Если быстро водить мышкой по картинке туда-сюда, то снизу добавляются сразу несколько Loading..., которые по прошествии некоторого времени все убираются(т.е., ошибки не произошло, просто block() выполнялось слишком долго). В block -- синхронный XNLHttpRequest, если что.

Да, JS в экстеншене.

Есть подозрение, что из-за того что JS в экстеншне, а не на странице всё дело и происходит. На обычной странице тот-же код работает?

>никаких проблем с вызовом параллельных потоков там нету.

И не должно быть. Просто это уже не есть концепция обработки сообщений в чистом виде.

Нет, наверное, потому, что это полностью заблокирует обработку всех сообщений. Возможно, даже, сразу во всех вкладках и окнах браузера.

В общем, скорее всего вам это не нужно.

Синхронный XMLHTTPRequest почему-то обработку сообщений не блокирует, даже если сервер не отвечает достаточно долго.

Проще разорвать искомую функцию и зарегистрировать timeOut с колбэком второй части.

Или, может, если до 10000 залупить нельзя предлагать, то может подойдёт посчитать до нужного Date?

на тему multithreading http://www.neilmix.com/2007/02/07/threading-in-javascript-17/ а по сабжу: залупить до нужного Date это и будет херовенькиий аналог sleep(). или через setTimeout() f1 = function(){...} f2 = funnction(){...} fuunction main() { f1(); setTimeout(f2, 666); }

на тему multithreading
http://www.neilmix.com/2007/02/07/threading-in-javascript-17/

а по сабжу:
залупить до нужного Date это и будет херовенькиий аналог sleep().

или через setTimeout()

f1 = function(){...}
f2 = funnction(){...}

fuunction main()
{
f1();
setTimeout(f2, 666);
}

Если ваша архитектура требует классов, подумайте еще. По аналогии, если ваша процедура требует sleep() - подумайте еще.

Continuations passing style

На setTimeout можно написать sleep, а на sleep - нельзя setTimeout. Вам просто дали более мощный инструмент.

:) программы не должны ждать, программы должны работать?

RE: updates

Не забывай, что интерфейсы самого браузера и того же Thunderbird сами частично написаны на JS, но этот JS совсем не так организован как веб-страничный и логика одного в логику другого не переносится.