JS · Урок 14

JS: async и fetch

Всё, что мы делали до сих пор, происходило мгновенно. Запрос к серверу занимает сотни миллисекунд — поэтому JavaScript использует асинхронность: не ждём, а «обещаем» вернуться с данными.

Промис — обещание

Промис — объект, который пока находится в состоянии «в работе», а потом перейдёт в «готово» (резолв) или «ошибка» (реджект). С двойной стрелкой оставляем себе два обработчика:

const promise = fetch("https://jsonplaceholder.typicode.com/todos/1");
promise.then(res => console.log(res)).catch(e => console.log(e));
ℹ️
У промиса два «кармана»: результат и ошибка. .then ловит результат, .catch — ошибку. Сцеплять их можно сколько угодно: .then(a).then(b).catch(c).

async / await: читабельная асинхронность

Та же логика без цепочек: функция помечается async, а перед долгими операциями пишем await — код приостанавливается и ждёт результат.

async function loadTodo() {
  try {
    const res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
    if (!res.ok) throw new Error("Ответ сервера: " + res.status);
    const data = await res.json();
    console.log(data.title);
  } catch (e) {
    console.error("Не удалось: ", e);
  }
}
loadTodo();
⚠️
Не заменяйте response.ok лишь статусом. Сетевые ошибки ловятся в catch, а вот «404 не найдено» приходит как успешный ответ — его проверяют отдельно через res.ok или res.status.

Показываем данные на странице

Классический приём: загрузили массив — отрисовали карточки. Всё знакомое: map, createElement, textContent — только данные пришли из интернета.

async function renderUsers() {
  const list = document.getElementById("users");
  try {
    const res = await fetch("https://jsonplaceholder.typicode.com/users");
    if (!res.ok) throw new Error("Ошибка " + res.status);
    const users = await res.json();
    users.slice(0, 5).forEach(user => {
      const li = document.createElement("li");
      li.textContent = user.name + " — " + user.email;
      list.appendChild(li);
    });
  } catch (e) {
    list.textContent = "Не удалось загрузить: " + e.message;
  }
}

Что ещё умеет fetch

Вторым аргументом передаём параметры запроса — так отправляют данные или указывают авторизацию.

fetch("/api/order", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "Ира", count: 2 })
});
💡
JSON из jsonplaceholder.typicode.com — бесплатный полигон для практики: 10 пользователей, 100 дел, 100 постов. Отличное место для первого «живого» fetch.