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

Асинхронный код

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

Что такое стек вызовов?

Стек вызовов — это структура данных, которая сообщает нам, где в программе мы сейчас находимся. Стопка похожа на стопку тарелок в буфете. Вы можете класть вещи только на вершину стопки, а когда вы хотите получить тарелку, вы можете убрать ее только сверху. Это также известно как структура данных LIFO (последний пришел — первый ушел). Стек вызовов проходит через программу JavaScript, выполняя каждый фрагмент кода строка за строкой.

function square (x) {        
  return x * x;
}
function doStuff (x) {
  return (x * 2) + square(x);                |
}                                            |
function showStack (x){
  console.log(doStuff(x));
}
showStack(10);
Call Stack:
|| square(x)    ||
|| doStuff(x)   ||
|| showStack(10)||
==================

Очередь задач

Очередь задач — это еще одна структура данных, которая содержит код JavaScript. Очередь — это структура данных FIFO (первым пришел — первым обслужен). Очередь задач — это место, где асинхронный код выстраивается в очередь для выполнения. Очередь задач удаляется из очереди и помещается в стек вызовов только тогда, когда стек вызовов очищается.

Цикл событий

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

Заключительные мысли и резюме

Это общий обзор того, что влечет за собой цикл событий. Есть и другие крошечные кусочки, которые являются частью этого цикла и являются концептами более низкого уровня. Другие концепции включают WebAPI, который отслеживает внутренний таймер событий, когда вызываются такие вещи, как setTimeout, и дает нам возможность делать HTTP-запросы XML. Сам интерпретатор JavaScript, который постоянно работает в фоновом режиме, выполняя такие действия, как сбор мусора из неиспользуемых пространств памяти для максимальной эффективности, отслеживание событий, которые необходимо поместить в стек вызовов, загрузка файлов JavaScript и так далее.

В целом, общий рабочий процесс цикла событий заключается в том, что когда интерпретатор синхронно выполняет код JavaScript, он добавляет каждую вызванную функцию в стек вызовов и извлекается из стека, когда достигает оператора возврата или конца функции, которая является неявный возврат. Если интерпретатор встречает асинхронный фрагмент кода (например, HTTP-запрос XML, setTimeout и т. д.), он добавляется в стек вызовов и выполняется точно так же, как и любая функция, но об обработке самих данных заботится WebAPI. пока таймер не завершится или не получит ответ. После завершения процесса WebAPI добавляет завершенный запрос в очередь задач. Цикл событий ожидает, пока стек вызовов очистится, а затем удаляет очередь задач и помещает задачу в стек вызовов для выполнения, и цикл продолжается.