Что происходит, когда вы запускаете код JavaScript?

Код JavaScript работает в среде выполнения JavaScript - браузере, который вы используете. Среда выполнения JavaScript использует движок JavaScript, который преобразует код JavaScript в машинный код. Движок JavaScript для Chrome и узла - V8, для Mozilla - SpiderMonkey, для Safari - Nitro и для IE - Chakra.

Движок JavaScript состоит из кучи памяти и стека вызовов. В куче памяти хранятся все переменные, определенные в нашем коде JavaScript, в то время как стек вызовов выполняет операции (выполнение функции). Среда выполнения JavaScript предоставляет дополнительные функции, такие как прослушиватели событий, запросы HTTP / AJAX, функции синхронизации и т. Д., Для поддержки выполнения кода JavaScript.

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

Когда мы посмотрим на определение JavaScript, мы обнаружим, что JavaScript является однопоточным, что означает, что он имеет только один стек вызовов. Один стек вызовов подразумевает, что одновременно может выполняться только один фрагмент кода. Когда функция помещается в стек вызовов, контекст выполнения кода JavaScript - это функция на вершине стека вызовов.

JavaScript также известен своим неблокирующим поведением. Неблокирование означает, что JavaScript не ждет ответа на вызов API, запрос Ajax, событие ввода-вывода или таймер, а переходит к другому блоку кода под ним. Но как JavaScript работает без блокировки, если у него только один поток? Ответ заключается в том, что эти запросы выполняются веб-API (библиотека C ++ в случае узла), у которых есть собственный поток. Это делает возможным параллелизм в JavaScript.

Как мы знаем, когда вызывается функция с асинхронным обратным вызовом, вызов функции помещается в стек вызовов. И когда выполняется асинхронный вызов веб-API в этом блоке функции, запрос передается веб-API, а вызов функции извлекается из стека вызовов. Затем новая задача помещается в стек вызовов и выполняется. Тем временем веб-API выполняет запрос.

На стороне веб-API по завершении HTTP-запроса функция обратного вызова отправляется в очередь обратного вызова (очередь событий). Эти функции обратного вызова остаются в очереди обратного вызова, пока стек вызовов не пуст. Как только стек вызовов становится пустым, функция обратного вызова в начале очереди обратного вызова помещается в стек вызовов, и механизм JavaScript начинает выполнение этого блока функции обратного вызова.

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

Как среда выполнения узнает, что стек вызовов пуст и как вызываются события в очереди обратного вызова? Все это выполняется петлей событий.

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

Цикл событий перемещает первое событие из четной очереди в пустой стек вызовов. Цикл событий продолжает работать бесконечно, даже если очередь обратного вызова пуста (но в node это не так).

Вывод

  1. JavaScript является однопоточным, поскольку имеет только один стек вызовов, в котором выполняется функция.
  2. Контекст выполнения - это функция на вершине стека вызовов, которая выполняется в данный момент.
  3. JavaScript не блокирует, потому что медленные процессы, требующие вызова веб-API, выполняются в веб-API, оставляя стек вызовов открытым для выполнения других функций.
  4. JavaScript выполняется одновременно, потому что веб-API обрабатывает сделанные ему вызовы, в то время как механизм JavaScript продолжает выполнять другой блок кода.
  5. JavaScript, хотя и является синхронным, ведет себя асинхронно, потому что веб-API добавляет обратный вызов в очередь обратного вызова (очередь событий), которая затем отправляет обратный вызов в стек вызовов для выполнения.
  6. Цикл обработки событий проверяет наличие событий в очереди обратных вызовов и помещает их в пустой стек вызовов.