Skip to content

Асинхронный код: Promise и await

Почему ожидание ответа не останавливает страницу и как получить результат позже.

On this page

Когда программа читает данные из сети, ответ приходит не сразу. Если бы браузер останавливал всю страницу до ответа, кнопки и прокрутка перестали бы работать. Поэтому JavaScript может начать операцию, продолжить другие действия и обработать результат позже.

Результат, который появится позже

Promise – объект, представляющий будущий результат операции. Он может завершиться успешно или с ошибкой. В следующем примере setTimeout вызывает функцию через полсекунды, а Promise сообщает, когда ожидание закончилось:

main.js
function wait(milliseconds) {
  return new Promise((resolve) => {
    setTimeout(resolve, milliseconds);
  });
}
 
async function showResult() {
  console.log("Начали ожидание");
  await wait(500);
  console.log("Полсекунды прошли");
}
 
showResult();
console.log("Эта строка выполнится раньше окончания ожидания");

Сначала появится «Начали ожидание», затем сообщение про строку, и только потом – «Полсекунды прошли». await приостанавливает текущий вызов showResult, но не всю страницу. Слово async перед функцией разрешает использовать внутри нее await. Такая функция сама возвращает Promise.

Если операция закончилась ошибкой

Сетевой запрос может не выполниться. Для обработки ошибки используйте try и catch:

main.js
async function loadProducts() {
  try {
    const response = await fetch("/api/products");
    if (!response.ok) {
      throw new Error("Сервер вернул ошибку");
    }
 
    const products = await response.json();
    console.log(products);
  } catch (error) {
    console.error("Не удалось загрузить товары", error);
  }
}

fetch отправляет запрос и возвращает Promise с ответом. response.json() тоже возвращает Promise: преобразование тела ответа занимает время. Адрес /api/products здесь пример: чтобы код заработал в вашем проекте, нужен серверный обработчик по этому адресу. Проверка response.ok нужна потому, что HTTP-ответ с кодом ошибки сам по себе не обязательно приводит в catch.

В Next-03 вы встретите async у серверной функции формы. Там ожидание относится к серверной работе, а идея та же: результат появится позже. Для подробностей используйте руководство MDN по промисам и раздел про async и await.