4. Promise в JavaScript


Промисы в JavaScript — это специальные объекты, которые помогают работать с асинхронными операциями (например, загрузка данных с сервера, чтение файлов, таймеры). Они упрощают обработку действий, которые занимают время, и избавляют от «ада колбэков».

Аналогия из жизни

Представьте, что вы заказали пиццу:

Вы делаете заказ — это начало операции.

Вам дают чек с номером (промис) — это гарантия, что вы получите результат (пиццу или ошибку, если её испортят).

Вы можете заняться другими делами, пока пиццу готовят (ожидание).

Когда пицца готова, вас уведомляют (успех), либо говорят, что пиццы не будет (ошибка).

Состояния промиса

У промиса есть 3 состояния:

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

Создание промиса

Промис создается через конструктор new Promise. Он принимает функцию с двумя аргументами: resolve (для успеха) и reject (для ошибки).

const pizzaOrder = new Promise((resolve, reject) => {
  const isReady = true; // Симуляция успешного заказа
  if (isReady) {
    resolve("Пицца готова!"); // Успех
  } else {
    reject("Пицца сгорела!"); // Ошибка
  }
});

Использование промиса

Через методы .then(), .catch() и .finally():

  • .then() — выполняется при успехе.
  • .catch() — выполняется при ошибке.
  • .finally() — выполняется в любом случае.
pizzaOrder
  .then((result) => {
    console.log(result); // "Пицца готова!"
  })
  .catch((error) => {
    console.error(error); // "Пицца сгорела!"
  })
  .finally(() => {
    console.log("Операция завершена."); // Будет в любом случае
  });

Зачем это нужно?

Без промисов код превращался бы в «ад колбэков»:

// Раньше писали так:
getData(function(data) {
  processData(data, function(processedData) {
    saveData(processedData, function() {
      console.log("Готово!");
    }, handleError);
  }, handleError);
}, handleError);

С промисами:

getData()
  .then(processData)
  .then(saveData)
  .then(() => console.log("Готово!"))
  .catch(handleError); // Все ошибки ловятся здесь