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

JavaScript — это однопоточный язык. Это означает, что одновременно может выполняться только одна задача. Или, другими словами, код JavaScript работает таким образом, что за раз выполняется одна строка.

Итак, теперь, если мы представим, нам нужно запустить асинхронную операцию, такую ​​​​как получение данных из API, которая требует 30 секунд, поэтому ожидание 30 секунд, прежде чем что-то еще может произойти, не будет идеальной ситуацией. Итак, здесь на сцену выходит концепция цикла событий.

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

1. Стек выполнения/стек вызовов
Стек выполнения в обычных словах аналогичен стеку в структурах данных, где соблюдается принцип LIFO. В JavaScript стек выполнения используется для отслеживания вызовов функций. Как только функция вызывается, она помещается в стек, а после завершения извлекается.

2. Веб-API
Веб-API позволяют нам использовать функции, предоставляемые браузерами, в наших веб-приложениях. Вот несколько примеров: setTimeout, выборка, HTTP-запросы, localStorage, геолокация и т. д.

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

Теперь давайте разберемся с приведенными выше концепциями на примере:

Output of above example:
Hello, I am first
Welcome to event loop example
Byee // after 1 second

Пояснение с диаграммой:

Пояснение:

  1. Прежде всего, функция hello() в line 13 помещается в execution stack, и как только она записывает значение “Hello, I am first” в консоль, ее выполнение завершается, и она выталкивается.
  2. Теперь, переходя к line 14, у нас есть setTimeout() со временем 1000ms or 1s и функцией обратного вызова bye(). Теперь он помещается в execution stack.
  3. Но поскольку setTimeout() является частью Web API, оно передается Web API, чтобы завершить таймер 1s.
  4. Теперь, в line 15, welcome() помещается в execution stack. И после регистрации “Welcome to event loop example” в консоли его выполнение завершается, и он выталкивается.
  5. Теперь предположим, что таймер 1s отработал, теперь функция bye() перемещается с Web APIs на Message Queue.
  6. Теперь execution stack будет пустым, так как все наши синхронные функции завершили свое выполнение.
    А bye() функция находится в message queue, здесь начинается Цикл событий.

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

Теперь, поскольку цикл обработки событий проверяет, что execution stack пуст, он помещает туда функцию bye(), а bye() завершает свое выполнение и извлекает себя.

Итак, вот как асинхронная операция выполнялась в приведенном выше примере с помощью setTimeout, и как цикл событий помог нам сделать это проще и лучше.

Надеюсь, статья оказалась для вас полезной.
Ставьте лайки и комментируйте, если она вам помогла.