Asynchronous Programming in JavaScript: A Complete Guide for Beginners

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Введение в асинхронное программирование в JavaScript

JavaScript — это однопоточный язык программирования с неблокирующей моделью ввода-вывода. Это означает, что в один момент времени выполняется только одна операция. Однако, благодаря асинхронному программированию, Node.js может обрабатывать тысячи запросов одновременно без блокировки основного потока. В этой статье мы разберём основные концепции асинхронности: колбэки (callbacks), промисы (Promises) и синтаксис async/await.



Что такое асинхронность и зачем она нужна?

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



В Node.js асинхронность особенно важна, потому что сервер должен одновременно обслуживать множество клиентов. Без неё каждый новый запрос блокировал бы работу всего приложения.



Синхронный vs Асинхронный код: пример

Рассмотрим простой пример чтения файла. Синхронный вариант блокирует выполнение:

const fs = require('fs');

// Синхронное чтение — блокирует потокconst data = fs.readFileSync('file.txt', 'utf8');console.log('Данные прочитаны:', data);console.log('Этот код выполнится только после чтения файла');


Асинхронный вариант не блокирует:

const fs = require('fs');

// Асинхронное чтение — не блокируетfs.readFile('file.txt', 'utf8', (err, data) => { if (err) throw err; console.log('Данные прочитаны:', data);});

console.log('Этот код выполнится сразу, не дожидаясь чтения файла');


Основные способы работы с асинхронностью

В JavaScript (и Node.js) существует три основных подхода к асинхронному программированию. Мы рассмотрим их от самых старых к современным.



1. Callback (функции обратного вызова)

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

function getUserData(userId, callback) {  setTimeout(() => {    const user = { id: userId, name: 'Анна' };    callback(null, user); // первый аргумент — ошибка (если есть)  }, 1000);}

getUserData(1, (err, user) => { if (err) { console.error('Ошибка:', err); return; } console.log('Пользователь:', user.name);});


Проблема: когда операций становится много, код превращается в "ад колбэков" (callback hell) — глубоко вложенные функции, которые сложно читать и отлаживать.



2. Promise (Промисы)

Promise — это объект, который представляет собой результат асинхронной операции. Он может находиться в одном из трёх состояний:

  • pending (ожидание) — операция ещё не завершена
  • fulfilled (выполнено) — операция завершена успешно
  • rejected (отклонено) — операция завершена с ошибкой


Промисы решают проблему callback hell и делают код более линейным:

function getUserData(userId) {  return new Promise((resolve, reject) => {    setTimeout(() => {      const user = { id: userId, name: 'Иван' };      // resolve — успех, reject — ошибка      resolve(user);      // reject(new Error('Пользователь не найден'));    }, 1000);  });}

// Использование цепочки .then()getUserData(1) .then(user => { console.log('Пользователь:', user.name); return user.id; }) .then(id => console.log('ID:', id)) .catch(err => console.error('Ошибка:', err)) .finally(() => console.log('Операция завершена'));

Blogs

Book Recommendations