JS Async

Часть пути: JS Intermediate

Синхронный код и блокировка

Понять, как JavaScript выполняет код последовательно, что такое call stack, и почему долгие операции блокируют интерфейс.

Средний (Intermediate)
Нужно знать:Стиль кода

Кратко

JavaScript выполняет код построчно в одном потоке. Каждый вызов функции добавляется в стек вызовов (call stack). Если операция занимает много времени — она блокирует весь интерфейс. Асинхронные механизмы позволяют запускать долгие операции, не блокируя основной поток.


Подробно

Call Stack (стек вызовов):

Когда JavaScript выполняет функцию, он помещает её в стек. Когда функция завершается — она удаляется из стека.

function first() { console.log('first'); } function second() { first(); console.log('second'); } second();

// Стек: [second] → [second, first] → [second] → [] // Вывод: first, second

Синхронный код выполняется последовательно. Если функция выполняется долго — весь код «ждёт».

Пример блокировки: function heavyComputation() { // Цикл на 5 секунд const start = Date.now(); while (Date.now() - start < 5000) {} console.log('Готово!'); }

heavyComputation(); // 5 секунд блокировки! console.log('Это выведется ПОСЛЕ'); // через 5 секунд

Почему это проблема:

  • Браузер не может обрабатывать клики
  • Анимации останавливаются
  • Страница «зависает»

В браузере есть один основной поток (main thread). JavaScript-код и обработка событий работают в одном потоке. Поэтому долгая синхронная операция блокирует всё.

Асинхронные механизмы: Браузер предоставляет механизмы для неблокирующего выполнения:

  • Таймеры (setTimeout)
  • Сетевые запросы (fetch)
  • События (addEventListener)

Эти операции выполняются параллельно основному потоку, а результат передаётся обратно через callback.


Ментальная модель

Call stack — как стопка тарелок. Каждый вызов функции — новая тарелка сверху. Когда функция завершается — тарелка убирается. Если стопка слишком высокая — она падает (Stack Overflow). Блокирующий код — как тяжёлая тарелка, которую невозможно убрать, пока она не «прогрузится».


Примеры

**Самый простой:**

javascript
console.log('1');
console.log('2');
console.log('3');
// Вывод: 1, 2, 3
// Синхронный код: строки выполняются по порядку.

Синхронный код выполняется последовательно, строка за строкой.

**Простой:**

javascript
function a() { console.log('a'); }
function b() { a(); console.log('b'); }
function c() { b(); console.log('c'); }

// Стек: [c] → [c, b] → [c, b, a] → [c, b] → [c] → []
// Вывод: a, b, c

Вложенные вызовы: стек растёт при входе и уменьшается при выходе.

**Реальный пример:**

javascript
// Блокировка UI:
const button = document.querySelector('#myButton');
button.addEventListener('click', () => {
  console.log('Клик!');
  // Блокирующий цикл:
  const start = Date.now();
  while (Date.now() - start < 3000) {}
  console.log('Готово!');
  // 3 секунды: кнопка не реагирует, анимации стоят
});

Блокирующий код в обработчике событий «замораживает» интерфейс.


Частые ошибки

**Неправильно:** Думать, что JavaScript многопоточный

**Почему:** JavaScript — однопоточный (main thread). Браузер может выполнять JS-код только в одном потоке.

**Правильно:** JavaScript — один поток. Браузер использует Web Workers и APIs для параллельной работы.

**Неправильно:** Использовать циклы для ожидания

**Почему:** while (Date.now() < target) {} — блокирует весь поток.

**Правильно:** Используйте setTimeout, Promises или async/await для неблокирующего ожидания.

**Неправильно:** Путать setTimeout(fn, 0) с немедленным выполнением

**Почему:** setTimeout(fn, 0) планирует выполнение на следующий тик, а не выполняет немедленно.

**Правильно:** setTimeout(fn, 0) — «выполни, когда будет возможность», а не «прямо сейчас».


Важно запомнить

  • JavaScript — однопоточный (main thread)
  • Call stack — стек вызовов: функция вверх, завершение — вниз
  • Синхронный код блокирует выполнение следующих строк
  • Блокирующие операции «замораживают» интерфейс
  • Асинхронные механизмы позволяют работать без блокировки

Связь

Назад: Вы знаете JavaScript Core и Intermediate (J0-JI19) — теперь вы понимаете, как выполнение устроено внутри.

Вперёд: Следующий урок (JA2) — callback-функции и setTimeout: первый асинхронный механизм.

Материалы курса JS Async — PROlab Academy.