Поскольку JavaScript выполняется в одном потоке, что на самом деле происходит в фоновом режиме после выполнения запроса AJAX? Я хотел бы получить более глубокое представление об этом, может ли кто-нибудь пролить свет?
Поскольку JavaScript выполняется в одном потоке, что на самом деле происходит в фоновом режиме после выполнения запроса AJAX? Я хотел бы получить более глубокое представление об этом, может ли кто-нибудь пролить свет?
Ответы:
Под обложками у javascript есть очередь событий. Каждый раз, когда поток выполнения javascript завершается, он проверяет, есть ли в очереди другое событие для обработки. Если есть, он извлекает его из очереди и запускает это событие (например, щелчок мышью).
Сеть на собственном коде, которая находится под вызовом ajax, будет знать, когда ответ ajax будет выполнен, и событие будет добавлено в очередь событий javascript. Как собственный код узнает, когда выполняется вызов ajax, зависит от реализации. Он может быть реализован с помощью потоков или также может управляться событиями (на самом деле это не имеет значения). Суть реализации заключается в том, что когда ответ ajax выполнен, некоторый собственный код будет знать, что это сделано, и поместит событие в очередь JS.
Если в это время не запущен Javascript, событие будет немедленно инициировано, что запустит обработчик ответа ajax. Если в это время что-то работает, событие будет обработано, когда текущий поток выполнения javascript завершится. Никакого опроса движком javascript не требуется. Когда часть Javascript завершает выполнение, JS-движок просто проверяет очередь событий, чтобы увидеть, есть ли что-то еще, что нужно запустить. Если это так, он выталкивает следующее событие из очереди и выполняет его (вызывая одну или несколько функций обратного вызова, которые зарегистрированы для этого события). Если в очереди событий ничего нет, то у интерпретатора JS есть свободное время (сборка мусора или бездействие), пока какой-либо внешний агент не поместит что-то еще в очередь событий и снова не разбудит его.
Поскольку все внешние события проходят через очередь событий, и никакое событие никогда не запускается, пока javascript фактически выполняет что-то еще, он остается однопоточным.
Вот несколько статей о деталях:
.focus()
элемент, и это запускает пару других событий, таких как событие «размытия» на элементе с фокусом. Это событие размытия происходит синхронно и не проходит через очередь событий, поэтому оно должно произойти сразу же, прежде чем другие вещи, которые могут быть в очереди событий. На практике я никогда не сталкивался с практическими проблемами.
Вы можете найти здесь очень полную документацию о событиях обработки в JavaScript.
Он написан парнем, работающим над реализацией javascript в браузере Opera.
Точнее, посмотрите на заголовки: «Поток событий», «Очередь событий» и «Непользовательские события»: вы узнаете, что:
Примечание. Первоначальная ссылка была: ссылка , но теперь она мертва.
Я хочу немного рассказать о реализации ajax, упомянутой в ответах.
Хотя (обычное) выполнение Javascript не является многопоточным, как это хорошо отмечено в приведенных выше ответах, однако реальная обработка AJAX responses
(а также обработка запросов) - это не Javascript, и он, как правило, является многопоточным. (см. реализацию XMLHttpRequest в источнике хрома, которую мы обсудим выше)
и я объясню, возьмем следующий код:
var xhr = new XMLHttpRequest();
var t = Date.now;
xhr.open( "GET", "https://swx.cdn.skype.com/shared/v/1.2.15/SkypeBootstrap.min.js?v="+t(), true );
xhr.onload = function( e ) {
console.log(t() + ': step 3');
alert(this.response.substr(0,20));
};
console.log(t() + ': step 1');
xhr.send();
console.log(t() + ': step 2');
after an AJAX request is made
(- после шага 1), затем, пока ваш js-код продолжает выполнение (шаг 2 и после), браузер начинает настоящую работу: 1. форматирование tcp-запроса 2. открытие сокета 3. отправка заголовков 4. подтверждение связи 5. отправка тело 6. ожидание ответа 7. чтение заголовков 8. чтение тела и т. д. вся эта реализация обычно запускается в другом потоке параллельно с выполнением вашего js-кода. для примера, упомянутая реализация хрома использует Threadable Loader go digg-into 😉 (вы также можете получить некоторое впечатление, посмотрев на сетевую вкладку загрузки страницы, вы увидите несколько одновременных запросов).
В заключение я бы сказал, что, по крайней мере, большинство ваших операций ввода-вывода можно выполнять одновременно / асинхронно (и вы можете воспользоваться этим, используя, например, ожидание ). но все взаимодействия с этими операциями (выдача, выполнение обратного вызова js) синхронны.