← Назад к вопросам

Что такое async/await и как они связаны с Promise?

1.3 Junior🔥 251 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Async/Await и их связь с Promise

async/await — это синтаксический сахар над Promise, который делает асинхронный код похожим на синхронный. Это облегчает чтение и отладку кода, работающего с асинхронными операциями.

Promise — основа async/await

Promise — это объект, представляющий состояние асинхронной операции:

// Создание Promise
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Success!');
  }, 1000);
});

// Использование .then()
promise
  .then((result) => console.log(result))
  .catch((error) => console.error(error));

Состояния Promise:

  • Pending — в процессе
  • Fulfilled — выполнено с результатом
  • Rejected — отклонено с ошибкой

Async функция — оборачивает результат в Promise

// Обычная функция
function getData() {
  return 'hello';
}
console.log(getData()); // 'hello'

// Async функция ВСЕГДА возвращает Promise
async function getDataAsync() {
  return 'hello';
}
console.log(getDataAsync()); // Promise { 'hello' }

// Эквивалентно:
function getDataPromise() {
  return Promise.resolve('hello');
}

Await — паузирует выполнение до разрешения Promise

// Await можно использовать ТОЛЬКО внутри async функции
async function fetchUser() {
  const response = await fetch('https://api.example.com/user');
  const data = await response.json();
  return data;
}

// Это эквивалентно:
function fetchUserWithThen() {
  return fetch('https://api.example.com/user')
    .then((response) => response.json())
    .then((data) => data);
}

// Или еще более явно:
function fetchUserWithThen2() {
  return fetch('https://api.example.com/user')
    .then((response) => response.json())
    .then((data) => Promise.resolve(data));
}

Сравнение: Promise vs Async/Await

1. Простой запрос

С Promise:

function getUser(id) {
  return fetch(`/api/users/${id}`)
    .then((response) => response.json())
    .then((user) => user);
}

getUser(1).then((user) => console.log(user));

С async/await:

async function getUser(id) {
  const response = await fetch(`/api/users/${id}`);
  const user = await response.json();
  return user;
}

const user = await getUser(1);
console.log(user);

2. Последовательные операции

С Promise (callback hell):

function process() {
  return fetch('/api/data')
    .then((r) => r.json())
    .then((data) => fetch(`/api/details/${data.id}`))
    .then((r) => r.json())
    .then((details) => fetch(`/api/comments/${details.id}`))
    .then((r) => r.json())
    .then((comments) => ({
      data,
      details,
      comments,
    }));
}

С async/await (читаемо):

async function process() {
  const dataResponse = await fetch('/api/data');
  const data = await dataResponse.json();
  
  const detailsResponse = await fetch(`/api/details/${data.id}`);
  const details = await detailsResponse.json();
  
  const commentsResponse = await fetch(`/api/comments/${details.id}`);
  const comments = await commentsResponse.json();
  
  return { data, details, comments };
}

3. Параллельные операции

Неправильно (последовательно):

async function getMultipleUsers() {
  const user1 = await fetch('/api/users/1').then(r => r.json()); // Ждёт
  const user2 = await fetch('/api/users/2').then(r => r.json()); // Ждёт
  // Итого: 2 секунды, если каждый запрос 1 секунда
  return { user1, user2 };
}

Правильно (параллельно):

async function getMultipleUsers() {
  const [user1, user2] = await Promise.all([
    fetch('/api/users/1').then(r => r.json()),
    fetch('/api/users/2').then(r => r.json()),
  ]);
  // Итого: 1 секунда (параллельно)
  return { user1, user2 };
}

Обработка ошибок

С Promise (.catch):

fetch('/api/data')
  .then((r) => r.json())
  .then((data) => console.log(data))
  .catch((error) => console.error('Error:', error));

С async/await (try/catch):

async function getData() {
  try {
    const response = await fetch('/api/data');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error('Error:', error);
  }
}

Важные моменты

1. Async функция ВСЕГДА возвращает Promise

async function test() {
  return 42;
}

const result = test();
console.log(result instanceof Promise); // true
console.log(result); // Promise { 42 }

// Чтобы получить значение:
result.then((value) => console.log(value)); // 42
// Или:
const value = await test();
console.log(value); // 42

2. Await можно использовать только в async функции

// Ошибка!
const data = await fetch('/api/data'); // SyntaxError!

// Правильно:
async function main() {
  const data = await fetch('/api/data');
}

// Или top-level await (в модулях)
await fetch('/api/data');

3. Ошибка в Promise внутри async

async function test() {
  throw new Error('Oops');
}

// Ошибка становится rejection
test()
  .catch((e) => console.log(e.message)); // 'Oops'

Promise.all / Promise.race / Promise.allSettled

// Ждёт ВСЕ promises (быстро падает на первую ошибку)
await Promise.all([promise1, promise2, promise3]);

// Ждёт ПЕРВЫЙ результат
await Promise.race([promise1, promise2]);

// Ждёт ВСЕ (не падает на ошибку)
await Promise.allSettled([promise1, promise2]);

Практический пример: API с retry

async function fetchWithRetry(url, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url);
      if (!response.ok) throw new Error(`Status ${response.status}`);
      return await response.json();
    } catch (error) {
      if (i === retries - 1) throw error;
      await new Promise((r) => setTimeout(r, 1000 * (i + 1)));
    }
  }
}

// Использование
const data = await fetchWithRetry('https://api.example.com/data');

Чеклист

✅ Async/await — это синтаксис для работы с Promise ✅ Async функция всегда возвращает Promise ✅ Await паузирует выполнение до разрешения Promise ✅ Используй try/catch для обработки ошибок ✅ Используй Promise.all для параллельных операций ✅ Await можно использовать только в async функции ✅ Async/await делает код более читаемым, чем .then().then()

Вывод: async/await — это современный способ работать с Promise. Они дают тот же результат, но async/await код выглядит как синхронный и легче читается.