2011-11-01 2 views
5

Я всегда слышу, что JavaScript однопоточный; что когда выполняется JavaScript, все они запускаются в одной и той же глобальной яме mosh, все в одном потоке.JavaScript и однопоточность

Хотя это может быть правдой, этот единственный поток выполнения может порождать новые потоки, асинхронный запрос данных обратно в основной поток, правильно? Например, когда отправляется XMLHttpRequest, разве браузер не создает новый поток, который выполняет транзакцию HTTP, а затем вызывает обратные вызовы в основном потоке, когда возвращается XMLHttpRequest?

Как насчет таймеров - setTimeout и setInterval? Как они работают?

Является ли эта однопоточность результатом языка? Что остановило JavaScript от многопоточного исполнения перед новым проектом Web Workers?

+0

переводчики javaScript часто обмениваются браузерами. Пользовательский интерфейс – david

+2

следующий раз, когда я говорю о глобальном охвате, я буду использовать термин ** global mosh pit ** :) –

+0

inb4 Веб-работники HTML5 – Ben

ответ

3

См. this post для описания того, как работает очередь событий javascript, в том числе о том, как она связана с вызовами ajax.

В браузере, конечно, используется хотя бы один поток/процесс собственной ОС для обработки фактического интерфейса с ОС для извлечения системных событий (мышь, клавиатура, таймеры, сетевые события и т. Д.). Существует ли более чем один родной поток уровня ОС, зависит от реализации браузера и не имеет особого отношения к поведению Javascript. Все события из внешнего мира проходят через очередь событий javascript, и никакое событие не обрабатывается до тех пор, пока предыдущий поток выполнения javascript не будет завершен, а затем последующее событие вытащится из очереди, заданной механизму javascript.

4

Ваш JavaScript сам по себе является однопоточным. Однако он может взаимодействовать с другими потоками в браузере (который часто пишется с помощью чего-то вроде C и C++). Вот как работает асинхронная XHR. Браузер может создать новый поток (или он может повторно использовать существующий с циклом событий.)

Таймеры и интервалы будут пытаться выполнить ваш JavaScript позже, но если у вас есть работающий while(1){ ; }, не ожидайте таймер или интервал для его прерывания.

(редактирование: осталось что-то.) Однопоточность в значительной степени является результатом спецификации ECMA. Там действительно нет языковых конструкций для работы с несколькими потоками. Невозможно было бы написать интерпретатор JavaScript с несколькими потоками и инструменты для взаимодействия с ними, но никто этого не делает. Конечно, никто не сделает это в веб-браузере; это будет беспорядок все вверх. (Если вы делаете что-то серверное, например Node.js, вы увидите, что они избегали многопоточности в собственном JavaScript в пользу замкнутого цикла событий и дополнительной многопроцессорной обработки.)

6

XMLHttpRequest, в частности , не блокирует текущий поток. Однако его специфика в пределах среды выполнения не очерчена ни в одной спецификации. Он может работать в отдельном потоке или в текущем потоке, используя неблокирующий ввод-вывод.

установить таймеры, которые при запуске до нуля добавят в исполняемый стек элемент выполнения кода функции/обратного вызова, запустив механизм JavaScript, если выполнение кода остановлено. Другими словами, они говорят, что движок JavaScript делает что-то после того, как он закончил делать то, что он делает в настоящее время. Чтобы увидеть это в действии, установите несколько setTimeout (ы) в рамках одного метода и вызовите его.

0

У браузера могут быть другие темы, чтобы выполнить эту работу, но ваш код Javascript по-прежнему будет выполнен в одном потоке. Вот как это будет работать на практике.

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

Запрос AJAX будет работать аналогичным образом. Некоторые внутренние потоки браузера могут на самом деле подключаться к серверу и ждать ответа, и как только ответ будет доступен, разместите соответствующее сообщение в главной очереди событий, так что основной поток выполняет обработчик.

Во всех случаях ваш код будет выполнен по основной теме. Это не отличается от большинства других пользовательских интерфейсов, кроме того, что браузер скрывает эту логику от вас. На других платформах вам может потребоваться обработать отдельные потоки и обеспечить выполнение обработчиков в потоке пользовательского интерфейса.

0

Полагая это проще, чем говорить в терминах потоков, в общем (для браузеров, о которых я знаю) будет только один блок JavaScript, выполняемый в любой момент времени.

При выполнении асинхронного запроса Ajax или вызвать setTimeout или setInterval браузер может управлять их в другом потоке, но фактический код JS в обратных вызовов не будет выполняться до тех пор какой-то момент после того, исполняемой в данный момент блок кода не заканчивается. Он просто встает в очередь.

Простой тест, чтобы продемонстрировать это, если положить кусок относительно долго выполняющиеся кода после SetTimeout, но в том же блоке:

setTimeout("alert('Timeout!');", 5); 
alert("After setTimeout; before loop");  
for (var i=0, x=0; i < 2000000; i++) { x += i }; 
alert("After loop"); 

Если вы запустите выше, вы увидите «После SetTimeout ", тогда во время цикла будет пауза, после чего вы увидите« После цикла », и только после этого вы увидите« Тайм-аут! ». - хотя явно прошло намного больше 5 мс (особенно если вы закроете первое предупреждение).

Часто цитируемая причина для одного потока заключается в том, что он упрощает работу браузера по рендерингу страницы, потому что вы не получаете ситуации из множества разных потоков JavaScript, все пытающихся обновить DOM на одном и том же время.

0

Javascript - это язык, предназначенный для встраивания. Он может и использовался в программах, которые одновременно запускают javascript на разных рабочих потоках. Недостаточно требовать, чтобы встроенный язык явно контролировал создание новых потоков выполнения, но это, безусловно, можно было бы сделать, предоставив объекту хоста требуемые возможности. WHATWG фактически includes a justification for their decision not to push a standard concurrent execution capability for browsers.

Смежные вопросы