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

Если вы не знаете о V8, то это механизм выполнения javascript. V8 компилирует javascript непосредственно в машинный код перед его выполнением. Скомпилированный код дополнительно оптимизируется (и повторно оптимизируется) динамически во время выполнения на основе эвристики профиля выполнения кода.
Быстрый факт: V8 используется такими технологиями, как NodeJS, MongoDB, Couchbase и многое другое.

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

Да !!

Однопоточный просто означает, что код Javascript, который вы пишете, выполняется в одном потоке. Да, без параллелизма!

Первая мысль, которая должна прийти в голову каждому техническому специалисту: если он однопоточный, как он может быть неблокирующим или параллельным.
Что ж, ответ ... БРАУЗЕРЫ!

Сам Javascript является синхронным и блокирующим (и никто не может это изменить) , но среда, в которой он выполняется, может поддерживать эти два. Разработчики четко знали, что для достижения этих двух целей браузеры должны быть действительно умными.
Браузер предоставляет различные WebAPI, которые разработчик может использовать и позволять javascript работать асинхронно. Надеюсь, ты понял сейчас.

Компоненты среды выполнения javascript

  1. Стек вызовов
  2. Куча
  3. WebAPI
  4. Очередь обратного вызова
  5. Цикл событий
  6. Очередь рендеринга

Мы будем узнавать о них один за другим. Первые два просты и понятны.

$: Стек вызовов

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

$: Куча

Куча - это часть, в которой происходит все выделение памяти. Все созданные объекты хранятся в разделе кучи среды выполнения.

$: WebAPI

Если мы увидим исходный код Chrome V8, мы не найдем важных функций JavaScript, таких как setTimeout (), post (), get () и т. Д.
функции предоставляются браузером как WebAPI, чтобы JavaScript работал как асинхронный и неблокирующий. Любая асинхронная работа, которую необходимо выполнить, отправляется в браузер для завершения с использованием одного из многих рабочих потоков из пула потоков.

Но зачем нам WebAPI?

Как было сказано ранее, поскольку javascript - однопоточный язык. Любой тип кода блокировки уничтожит UI / UX приложения.

Под блокирующим кодом я имею в виду не только запросы AJAX, но и функции, выполнение которых может занять много времени. Как это:

$: Очередь обратного вызова

Чтобы понять очередь обратных вызовов, мы должны сначала понять обратные вызовы.
Функция обратного вызова, также известная как функция высшего порядка, - это функция, которая передается другой функции (давайте назовем эту другую функцию «OtherFunction») в качестве параметра, и эта функция обратного вызова вызывается (или выполняется) внутри otherFunction.
Итак, очередь обратных вызовов содержит все обратные вызовы, которые запрашиваются для выполнения.

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

$: Цикл событий

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

Давайте посмотрим на пример кода, чтобы понять это,

если мы посмотрим на код, кажется очевидным, что setTimeout () подождет 5 секунд, а затем отключится. Что ж, это не всегда тот случай, когда он срабатывает через 5 секунд.
Помните, я говорил вам, что JS является однопоточным ... Да, он будет запускаться только тогда, когда поток доступен для выполнения этого кода, то есть он будет выполняться только тогда, когда стек вызовов пуст.

Тайм-аут 0 мс не означает, что это будет выполнено немедленно. Но сначала эта функция будет отправлена ​​на выполнение в V8. Тем временем поток JS свободен для выполнения и принимает следующий оператор выполнения. Тем временем движок V8 помещает обратный вызов отправленной функции в очередь обратного вызова. Как только стек вызовов опустеет, цикл обработки событий выбирает функцию обратного вызова и отправляет ее в поток JS для выполнения.

Точно так же все веб-интерфейсы работают одинаково,

Так в V8 устанавливается async. Блок кода отправляется в webAPI для запроса XHR, который затем помещается в очередь задач и, в конечном итоге, в стек вызовов.

Функция onClick () аналогична. Когда мы нажимаем кнопку, функция onClick отправляется в webAPI для выполнения, и рабочий поток выполняет эту часть кода.

Очередь рендеринга

Пользователь выполняет непрерывные действия. Поэтому браузеру приходится перекрашивать экран, чтобы поддерживать бесперебойную работу. Обычно браузер перерисовывает экран через 16 мс, то есть со скоростью 60 кадров в секунду, но в то же время он также должен выполнять код JS, написанный разработчиком.
Он не может выполнить рендеринг, если внутри стека вызовов есть код. Рендеринг также рассматривается как обратный вызов, разница в том, что обратному вызову рендеринга дается наивысший приоритет (ну, браузер немного скупердяй ... да!) Через 16 мс обратный вызов рендеринга выдвигается на передний план. очереди рендеринга и цикл событий теперь ожидает очистки стека вызовов. Как только он обнаруживает, что стек пуст, он отправляет обратный вызов рендеринга для выполнения, т.е. происходит перерисовка экрана.

Большая картинка!!!

Первоначально опубликовано на сайте swayamraina.blogspot.com.
PS: Я обновляю свои блоги и перемещаю их на средний уровень coz I средний

Почтовые кредиты!

Если вы внимательно посмотрите на идею, это привело к рождению программирования, управляемого событиями, или, более формально, реактивного программирования.
На каждом уровне у нас может быть буферная очередь, в которой потоки могут отправлять задачи и возвращаться, чтобы забрать новые запросы. Следующий уровень пула потоков может забирать задачи из этой буферной очереди и может либо обрабатывать их полностью (если обработка содержится в их системе), либо выполнять некоторую обработку, а затем отправлять задачу в другую буферную очередь, где может произойти остальная обработка.

Подробнее откуда это взялось

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

Следите за нашей публикацией, чтобы увидеть больше историй о продуктах и ​​дизайне, представленных командой Журнала.