Автор оригинала: Diego Palacios Lepore.
Фото Caspar Camille Rubin на Unsplash
Независимо от наших знаний о JavaScript, в некоторых случаях мы, вероятно, никогда не поняли, что происходит под капотом, когда код изначально выполняется. Чтобы понять, что происходит за кулисами, я сделал некоторые исследования, поэтому этот пост меня делится тем, что я узнал. Я сделаю все возможное, объясняя эту тему как можно более четким, как я прохожу на следующих понятиях:
- Окружающая среда выполнения JavaScript.
- Двигатель JavaScript.
- Куча.
- Стек вызова.
- Контейнер веб-API.
- Очередь обратного вызова.
- Контур событий.
Перед выполнением JavaScript должен компилировать в код, компьютер может понять, и, как вы, возможно, догадались, браузер является тем, что делает работу компиляции (с Node.js, мы можем выполнить JS вне браузера, но в этой статье я собираюсь сосредоточиться на JS внутри браузера).
Среда выполнения JavaScript
У каждого браузера есть JavaScript Runtime Environment В котором вы можете подумать как большой контейнер, удерживающий другие меньшие контейнеры внутри, эти меньшие контейнеры – это веб-API, доступные разработчикам, чтобы они могли строить веб-приложения, программы и т. Д. Некоторые из этих API – Ajax , Дом дерево , среди прочего).
В дополнение к этому, JavaScript Runtime Environment имеет JavaScript Engine Отказ Каждый браузер имеет разные JavaScript Engine Отказ Эта статья основана на V8 JavaScript Engine , один Google Chrome использует.
Как только Chrome получает наш код, V8 делает быстрое сканирование для проверки, если у нас есть какие-либо ошибки синтаксиса, если он не найдет, он продолжает прочитать нашу строку кода по строке, чтобы перевести его в один компьютер, понял, что , бинарный код.
Ниже вы увидите графическое представление о том, как работает эта среда выполнения JS.
Теперь я продолжу и объясню каждый из шагов, упомянутых на изображении выше.
Куча
Когда двигатель JS столкнулся с переменными и функциональными объявлениями в коде, он хранит их в куче.
Стек вызова
Когда цифровой сигнал включает в себя функцию JS Engine Engine, он добавляет их в стек вызова (до тех пор, пока стек не обрабатывает другие вызовы). Если эта функция имеет переменные, двигатель JS отправляет их в кучу, если у него есть другие вызовы (функциональные вызовы), она добавляет их в верхнюю часть стека, или если это таймер или вызов ajax, он отправляется на Контейнер веб-API.
Затем он начинает выполнять код в каждой функции и в конце каждого, если не было указано значение, он возвращается неопределенным по умолчанию, поэтому на данный момент функция удаляется из стека, и так далее до стека пустой.
Это показывает нам, что JavaScript выполняется синхронно, в одном потоке. Он делает одно за один раз, он анализирует функцию, и как только она заканчивает обработку, эта функция удаляется из стека.
Стек представляет собой структуру данных, которая запускает Lifo (в последний раз в первую очередь). Никакой другой функции, но только один в верхней части стека будет сосредоточен или активен, а двигатель не будет перейти к следующей функции, если только один выше не удален из стека.
Ниже вы найдете видео, которое применяет эту процедуру и ссылки на другие справочные ресурсы, которые помогут вам подробно понять эти процессы.
Веб-API контейнер
Если один из вызовов представляет собой слушатель события (например, щелчок, мыши, и т. Д.), Запросы HTTP/AJAX или функции таймера, они отправляются непосредственно на контейнер веб-API и подождите, пока ни событие «Click» не будет срабатывает или реакция вызова AJAX получен или прошел время, указанное в Settimeate. Затем функции обратного вызова из них (которые являются анонимными функциями) отправляются на четвертый и последний контейнер, очередь обратного вызова (очередь вызовов).
Очередь обратного вызова
В качестве функций обратного вызова добавляются в этот контейнер, которые организованы в порядке прибытия (как указано в предыдущей точке), они ждут, пока стек не будет добавлен к нему, а в то же время в том порядке, в котором они были добавлены.
В отличие от стека вызовов, очередь обратного вызова – это структура данных, которая запускает FIFO (первым в первую очередь). Следовательно, функция обратного вызова, которая сначала входит, это тот, который выходит сначала, когда ее очередь перейти к стеку вызовов.
Контур событий
Этот парень отвечает за постоянно наблюдать за проверкой стека вызовов, если он пусто или нет, и если очередь обратного вызова имеет любую функцию в удержании.
Важно отметить, что независимо от того, является ли стек и очередь обратного вызова пустых, цикл события всегда будет наблюдать за ними, поскольку в любое время анонимная функция может прийти в очередь из контейнера Web API, который вступил в Стек, если он пуст.
Заключение
Итак, после понимания вышеупомянутого, вы можете согласиться со мной, что даже мысль иногда JavaScript, по-видимому, не работает асинхронно, он не делает, так как JavaScript может обрабатывать только одну функцию одновременно в стеке, является из-за справки веб-API Контейнер, очередь обратного вызова и цикл событий, который, кажется, работает асинхронно.
Для того, чтобы получить голову вокруг этого, вы найдете эту ссылку очень полезную, http://latentflip.com/loupe Отказ Я рекомендую смотреть видео Во-первых, это видео, где автор, Филипп Робертс, рассказывает о том, что происходит, когда JavaScript работает.
«Loupe – это небольшая визуализация, чтобы помочь вам понять, как вызовование JavaScript Call Stack/Event Loop/Queue Callback взаимодействуют друг с другом». Филипп Робертс
Каким черт возьми, вся петля событий? |. Филипп Робертс | Jsconf ЕС