Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Промисы

Промис (от английского promise — обещание) — это объект, который обещает результат в будущем. Пока действие не завершено, результата ещё нет; когда оно закончится, промис либо выполнится со значением, либо завершится ошибкой. На промисах построена вся современная асинхронная работа: запросы к серверу, чтение файлов, ожидание.

then

Чтобы получить результат промиса, в метод then() передают функцию. Она будет вызвана, когда значение появится:

const promise = Promise.resolve(42);
 
promise.then((value) => {
  console.log(value); // 42
});

Promise.resolve() создаёт уже выполненный промис — так удобно показать then() без лишнего кода.

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

У промиса три состояния. Из ожидания он переходит в одно из двух конечных и больше не меняется:

СостояниеЧто значит
pending — ожиданиеРезультата ещё нет
fulfilled — выполненЕсть значение, вызываются функции из then()
rejected — отклонёнПроизошла ошибка, вызываются функции из catch()

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

Свой промис создают через new Promise(). Внутрь передают функцию, которая вызывает resolve, когда результат готов:

const promise = new Promise((resolve) => {
  setTimeout(() => {
    resolve('Готово');
  }, 300);
});
 
promise.then((value) => {
  console.log(value); // Готово
});

Этот промис выполняется через 300 мс. Так оборачивают в промис старые функции, которые принимают колбэк.

Ошибки и catch

Второй параметр — reject — отклоняет промис с ошибкой. Перехватывает её метод catch():

const promise = new Promise((resolve, reject) => {
  reject(new Error('Сервер не отвечает'));
});
 
promise.catch((error) => {
  console.log(error.message); // Сервер не отвечает
});

Отклонённый промис без catch() оставляет в консоли сообщение Uncaught (in promise).

Цепочки

then() сам возвращает новый промис, поэтому вызовы выстраивают в цепочку. То, что вернула одна функция, получает следующая:

Promise.resolve(2)
  .then((value) => value * 10)
  .then((value) => value + 1)
  .then((value) => {
    console.log(value); // 21
  });

Один catch() в конце цепочки перехватит ошибку из любого её звена.

finally

Функция из finally() выполняется в любом случае — и при успехе, и при ошибке. Туда помещают завершающие действия, например скрытие индикатора загрузки:

Promise.reject(new Error('Нет связи'))
  .catch((error) => console.log(error.message))
  .finally(() => console.log('Загрузка окончена'));
// Нет связи
// Загрузка окончена

Частая ошибка

Забыть return внутри then(), если функция записана с фигурными скобками. Тогда следующее звено цепочки получит undefined:

Promise.resolve(5)
  .then((value) => {
    value * 2;
  })
  .then((result) => {
    console.log(result); // undefined
  });

Пишите return value * 2 или используйте короткую стрелку без скобок: (value) => value * 2.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.