JavaScript объект Promise
Функция executor выполняется синхронно при создании Promise, а обработчики
then() запускаются через очередь микрозадач. resolve(value) может принять состояние другого
Promise или thenable, а не сразу выполнить обещание. Повторные попытки завершения игнорируются. Публичных свойств
состояния или результата у экземпляра нет; Promise сам по себе не отменяет операцию.
Описание объекта Promise
Объект Promise (обещание) представляет из себя специальный объект, предназначенный для планирования
работы над значением, которое еще не было вычислено (завершение или сбой асинхронной операции). Объект
Promise представляет из себя абстракцию для управления взаимодействиями с асинхронными
API.
Объект Promise может находиться в следующих состояниях:
Начальное состояние любого объекта Promise - pending (ожидание). Если операция завершена успешно,
то объект Promise изменяет свое состояние на fulfilled (выполнено), в том случае если операция
завершена ошибкой, то объект Promise изменяет свое состояние на rejected (отклонено).
Еще один термин settled (решенный) используется для описания состояния объекта Promise, который
изменил свое состояние на fulfilled (выполнено), или rejected (отклонено).
Синтаксис объекта Promise
const promise = new Promise((resolve, reject) => {
resolve("Готово");
});
promise.then(value => console.log(value));
Значение параметра
| Параметр | Описание |
|---|---|
executor |
Представляет из себя объект функции, который принимает два аргумента: resolve и
reject. Аргументы представляют из себя функции, которые могут быть вызваны по завершению
операции, первый аргумент вызывает успешное выполнение обещания, а второй отклоняет его.
|
Ниже отдельно перечислены собственные статические методы Promise и методы его прототипа. Общие унаследованные возможности других объектов в таблицы не включены.
Статические методы Promise
| Метод | Описание |
|---|---|
all()
|
Ожидает успешного выполнения всех входных значений и возвращает массив результатов в исходном порядке. Отклоняется при первом отклонении; остальные операции не отменяются. |
race()
|
Принимает результат первого завершившегося элемента: успешное значение или причину отклонения. Пустой набор оставляет результат ожидающим. |
reject()
|
Создаёт новое отклонённое обещание с указанной причиной; причина не разворачивается как thenable. |
resolve()
|
Возвращает обещание, принимающее результат значения или thenable. Обещание с тем же конструктором возвращается без копирования. |
allSettled() |
Возвращает обещание с массивом результатов в порядке входа. Ждёт завершения всех элементов; каждый результат содержит status и value либо reason. Отклонение элемента не отклоняет итоговое обещание; пустой источник даёт []. |
any() |
Выполняется со значением первого успешно выполненного элемента. Если отклонены все, отклоняется с AggregateError; его errors упорядочены по входу. Пустой источник также приводит к отклонению. |
try() |
Синхронно вызывает callback(...args) и возвращает Promise, принимающий его результат или
исключение. В отличие от Promise.resolve(callback()), перехватывает синхронное исключение самого
вызова.
|
withResolvers() |
Возвращает объект { promise, resolve, reject }: новое ожидающее обещание и связанные с ним функции завершения. Само по себе не запускает операцию и не отменяет её. |
Методы экземпляра Promise
| Метод | Описание |
|---|---|
catch()
|
Добавляет обработчик или обработчики, которые будут вызваны при изменении состояния объекта
Promise на rejected (выполнение отклонено).
|
finally()
|
Регистрирует обработчик завершения без аргументов и возвращает новое обещание. Сохраняет исходный результат, кроме исключения или отклонения из обработчика. |
then()
|
Добавляет обработчик, или обработчики, вызываемые когда объект Promise имеет состояние
fulfilled (успешное выполнение), или rejected (выполнение отклонено).
|
Свойства Promise
| Свойство | Описание |
|---|---|
Promise.prototype |
Общий прототип экземпляров Promise; содержит then(), catch() и finally(). |
Promise[Symbol.species] |
Геттер конструктора, по умолчанию возвращающий this. Позволяет подклассам задавать конструктор
обещаний, создаваемых цепочкой then()/catch()/finally().
|
Promise.prototype.constructor |
Ссылка на конструктор, исходно Promise; наследуется экземплярами. |
Promise.prototype[Symbol.toStringTag] |
Унаследованная метка "Promise" для Object.prototype.toString(). Это не свойство
состояния обещания.
|
Promise.length |
Собственное свойство функции-конструктора: число формальных параметров, равное 1. |
Promise.name |
Собственное имя функции-конструктора: "Promise". |
Спецификация
Примеры, попробуйте сами
Синхронный executor и микрозадачи
Перенесите сообщения внутрь и наружу then(). Сравните порядок синхронного кода и обработчиков.
index.html
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>Синхронный executor и микрозадачи</title>
</head>
<body>
<p>Результат выполнения выводится в консоль.</p>
</body>
</html>
main.js
console.log('Начало')
const promise = new Promise((resolve) => {
console.log('executor')
resolve('Результат')
})
promise.then((value) => console.log(value))
console.log('Конец синхронного кода')
Все исходы и первый успех
Замените успешное значение отклонением. Сравните allSettled() и any(), включая пустые наборы.
index.html
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>Все исходы и первый успех</title>
</head>
<body>
<p>Результат выполнения выводится в консоль.</p>
</body>
</html>
main.js
const values = [Promise.reject('Ошибка'), Promise.resolve('Готово')]
Promise.allSettled(values).then((result) => console.log(result))
Promise.any(values).then(
(value) => console.log(value),
(error) => console.log(error.name)
)
Promise.allSettled([]).then((result) => console.log(result))
Promise.any([]).catch((error) => console.log(error.name, error.errors.length))
Внешний resolve и синхронное исключение
Измените значение resolve или тело функции в Promise.try(). Наблюдайте успешный результат и обработку ошибки.
index.html
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>Внешний resolve и синхронное исключение</title>
</head>
<body>
<p>Результат выполнения выводится в консоль.</p>
</body>
</html>
main.js
if (typeof Promise.withResolvers === 'function') {
const { promise, resolve } = Promise.withResolvers()
promise.then((value) => console.log(value))
resolve('Готово')
} else {
console.log('Promise.withResolvers() не поддерживается в этом браузере')
}
if (typeof Promise.try === 'function') {
Promise.try(() => {
throw new Error('Ошибка функции')
}).catch((error) => console.log(error.message))
} else {
console.log('Promise.try() не поддерживается в этом браузере')
}