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

Тема дорожной карты · Node.js

Асинхронное программирование — это фундаментальная концепция среды выполнения JavaScript Node.js, позволяющая однопоточному циклу событий обрабатывать тысячи одновременных I/O-операций без блокировки. Вместо ожидания завершения чтения файла, запроса к базе данных или сетевого вызова Node.js регистрирует колбэк, Promise или продолжение async/await и продолжает обрабатывать другие задачи, максимально используя ресурсы процессора. Три основных асинхронных паттерна в серверной разработке на Node.js — это колбэки с ошибкой в первом аргументе, Promise и async/await, каждый из которых является более высокоуровневой абстракцией над предыдущим. Понимание того, как асинхронный код взаимодействует с циклом событий, пулом потоков libuv и очередями микрозадач, критически важно для предотвращения скрытых гонок и узких мест производительности. Эффективное использование асинхронных API Node.js — таких как fs.promises, http.request, и npm-пакетов axios или node-fetch — является ключевым серверным навыком для любого JavaScript-разработчика.

Как это работает

Асинхронность — сердце Node: event loop libuv проходит фазы timers, pending I/O callbacks, idle/prepare, poll, check, close-callbacks. async/await — современный примитив; promises — механизм под капотом; callbacks — legacy. setImmediate запускается на следующей итерации; process.nextTick — до любого I/O, злоупотребление ломает loop. Worker threads (worker_threads) гонят JS параллельно; у них отдельные event loop, изолированная память, обмен сообщениями.

Когда применять

async/await — везде в новом коде; callbacks — для legacy или streams. Promise.all/allSettled — для параллельного I/O когда независимы. CPU-bound работа — в worker_threads или отдельный сервис; никогда не блокируйте main loop. AbortController — для отмены долгих операций. Профилируйте event-loop lag (perf_hooks.monitorEventLoopDelay) в production — устойчивый lag > 50ms = проблема.

Типичные ошибки

Ловушки Асинхронность: забытый await → unhandled promise rejection (Node логирует warning, скоро будет crash); Promise.all падает на первом, когда хотели partial success (Promise.allSettled); глубокие then-цепочки там, где async/await читался бы линейно; setTimeout(0) для "yield в loop" (используйте setImmediate); рекурсия, растящая stack вместо возврата promise.

Связанные понятия

Полезные ресурсы