Асинхронность в JavaScript

Асинхронность — способность выполнять операции без блокирования основного потока, позволяя программе продолжать работу во время ожидания.


📑 Оглавление


Зачем нужно

JavaScript однопоточный. Без асинхронности любой запрос к серверу, таймер или чтение файла «замораживало» бы интерфейс. Асинхронность позволяет обрабатывать длительные операции, не блокируя UI.

↑ к оглавлению

Где используется

  • HTTP-запросы (fetch, XMLHttpRequest)
  • Таймеры (setTimeout, setInterval)
  • Работа с файлами (Node.js)
  • Анимации (requestAnimationFrame)
  • WebSocket, Server-Sent Events
  • Базы данных (IndexedDB, серверные)

↑ к оглавлению

Предпосылки

Scope, Callbacks

↑ к оглавлению

Карта раздела

Асинхронность
├── Event Loop                       — механизм выполнения (host API, не JS!)
│   ├── Call Stack / Execution context stack
│   ├── Task Queue (Set)             — внешние API кладут сюда
│   ├── Microtask Queue              — Promise jobs, queueMicrotask
│   └── Reactor pattern              — что внутри event loop
├── Callbacks                        — базовый паттерн (callback-last, error-first)
│   └── Callback Hell                — решается Promise/async-await
├── Promise                          — цепочки и обработка ошибок
│   ├── then / catch / finally
│   ├── Promise.all / allSettled / any / race
│   ├── Promise.try (ES2025)
│   └── Promise.withResolvers (ES2024)
├── async/await                      — синтаксический сахар над генератором
│   ├── try/catch
│   ├── Параллельное выполнение
│   ├── Top-level await
│   └── Async stack trace
├── setTimeout / setInterval         — таймеры (тоже host API!)
├── Fetch API                        — HTTP-запросы
│   └── AbortController              — отмена через signal
├── Error handling                   — обработка ошибок (incl. unhandledRejection)
├── Поведенческие контракты JS       — Callable, Thenable, Iterable, ...
├── Thenable                         — контракт с then
├── Deferred                         — старый паттерн, сегодня = withResolvers
├── Future                           — ленивая монадическая альтернатива Promise
├── Cancellable Promise              — отмена async-операций
├── JS генераторы                    — yield, итерируемые корутины
├── Асинхронные генераторы           — async iterable, for-await-of
├── Promise Pattern                  — паттерны: parallel, race, retry, queue
├── Promisify, callbackify, asyncify — адаптеры между контрактами
├── AsyncPool                        — ограничение concurrency
└── Async композиция и коллекторы    — compose/pipe/branch/collect

↑ к оглавлению

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

// СИНХРОННЫЙ — каждая строка ждёт предыдущую
console.log('1');
console.log('2');
console.log('3');
// Вывод: 1, 2, 3

// АСИНХРОННЫЙ — некоторые операции откладываются
console.log('1');
setTimeout( => console.log('2'), 0); // отложено!
console.log('3');
// Вывод: 1, 3, 2

↑ к оглавлению

Эволюция асинхронности в JS

Callbacks (с начала JS)

getData(function(data) {
  getMore(data, function(more) {
    process(more, function(result) {
      // Callback Hell — «пирамида смерти»
    });
  });
});

Promise (ES2015)

getData
  .then(data => getMore(data))
  .then(more => process(more))
  .then(result => console.log(result))
  .catch(err => console.error(err));

async/await (ES2017)

async function main() {
  try {
    const data = await getData;
    const more = await getMore(data);
    const result = await process(more);
    console.log(result);
  } catch (err) {
    console.error(err);
  }
}

↑ к оглавлению

Что является асинхронным

Операция Тип задачи
setTimeout / setInterval Macrotask
fetch / HTTP-запросы Microtask (Promise)
Promise.then/catch/finally Microtask
queueMicrotask Microtask
MutationObserver Microtask
DOM-события (click, input) Macrotask
requestAnimationFrame Перед repaint
requestIdleCallback Когда браузер свободен

↑ к оглавлению

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

  1. Блокировка главного потока — тяжёлые вычисления в синхронном коде замораживают UI
  2. Забыл await — получаешь Promise вместо значения
  3. Последовательные запросы вместо параллельныхawait a; await b медленнее Promise.all
  4. Необработанные rejected Promise — приводят к UnhandledPromiseRejection

↑ к оглавлению

Практика

  1. Предскажи порядок вывода: console.log, setTimeout, Promise.resolve.then
  2. Перепиши цепочку callbacks в Promise, затем в async/await
  3. Сделай три параллельных fetch-запроса и обработай результаты

↑ к оглавлению

Связанные темы

Базовые механики

Promise / async-await

Сеть и отмена

Ошибки

Итераторы / корутины

Альтернативные модели

Прикладные паттерны

↑ к оглавлению

Ресурсы

↑ к оглавлению


🧭 Навигация

⬆ Родительский MOC _MOC JavaScript
⬆ К главной 🗺️ MOC

📑 Быстрое оглавление