Однопоточная природа JavaScript в сочетании с возможностью выполнения асинхронных операций является уникальной особенностью языка. Это стало возможным благодаря двум основным механизмам — циклу обработки событий и модели параллелизма. В этом посте мы подробно рассмотрим эти функции.

Модель параллелизма в JavaScript: однопоточная, но асинхронная

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

Давайте рассмотрим простой пример, чтобы проиллюстрировать, как это работает:

// First
console.log('Start');

// Second
setTimeout(() => {
  // Fifth: Callback function is not executed until after the delay.
  console.log('Timeout');
}, 2000);

// Third
console.log('End');

В приведенном выше коде вывод будет таким:

Start
End
Timeout

Несмотря на то, что setTimeout записано в коде перед console.log('End'), 'End' регистрируется до 'Timeout'. Это связано с тем, что setTimeout — это веб-API, предоставляемый браузером (а не сам JavaScript). Когда функция setTimeout запускается, браузер запускает таймер. Как только этот таймер заканчивается, функция обратного вызова помещается в очередь задач. Среда выполнения JavaScript проверяет эту очередь задач и помещает функцию обратного вызова в стек вызовов только тогда, когда стек вызовов пуст.

Цикл событий: более пристальный взгляд

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

Чтобы лучше проиллюстрировать работу цикла событий, давайте рассмотрим следующий пример:

// Define three functions
function foo() {
  console.log('Hello'); // 1: Logs 'Hello' immediately
  setTimeout(bar, 0); // 3: Starts a 0 second timer
  baz(); // 2: Calls the 'baz' function immediately
}

function bar() {
  console.log('World'); // 5: Logs 'World' after 'baz' finishes, despite the 0 second timer
}

function baz() {
  console.log('Goodbye'); // 4: Logs 'Goodbye' before 'bar' because 'bar' was offloaded to the browser
}

foo(); // Starts the 'foo' function

Вывод этого кода будет «Привет», «До свидания», «Мир». Несмотря на то, что setTimeout имеет значение 0, он помещается в очередь веб-API и выполняется только после выполнения всех функций в стеке вызовов (основном потоке).

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

Если вам понравилась статья и вы хотите выразить свою поддержку, сделайте следующее:

👏 Аплодируйте истории (50 аплодисментов), чтобы эта статья попала в топ

👉Подпишитесь на меня в Среднем

Посмотрите больше контента в моем профиле Medium