--- title: Promise slug: Web/JavaScript/Reference/Global_Objects/Promise tags: - ECMAScript6 - JavaScript - Promise - Промисы translation_of: Web/JavaScript/Reference/Global_Objects/Promise ---
Объект Promise используется для отложенных и асинхронных вычислений.
{{EmbedInteractiveExample("pages/js/promise-constructor.html")}}
Исходники интерактивного демо находятся в репозитории на GitHub. Если вы хотите внести свой вклад в развитие интерактивных демо, пожалуйста, склонируйте https://github.com/mdn/interactive-examples и отправьте нам пулреквест.
new Promise(executor);
new Promise(function(resolve, reject) { ... });
resolve и reject. Функция executor получает оба аргумента и выполняется сразу, ещё до того как конструктор вернёт созданный объект. Первый аргумент (resolve) вызывает успешное исполнение промиса, второй (reject) отклоняет его.executor описывает выполнение какой-то асинхронной работы, по завершении которой необходимо вызвать функцию resolve или reject. Обратите внимание, что возвращаемое значение функции executor игнорируется.Интерфейс Promise (промис) представляет собой обёртку для значения, неизвестного на момент создания промиса. Он позволяет обрабатывать результаты асинхронных операций так, как если бы они были синхронными: вместо конечного результата асинхронного метода возвращается своего рода обещание (дословный перевод слова "промис") получить результат в некоторый момент в будущем.
Promise может находиться в трёх состояниях:
При создании промис находится в ожидании (pending), а затем может стать исполненным (fulfilled), вернув полученный результат (значение), или отклонённым (rejected), вернув причину отказа. В любом из этих случаев вызывается обработчик, прикреплённый к промису методом then. (Если в момент назначения обработчика промис уже исполнен или отклонён, обработчик всё равно будет вызван, т.е. асинхронное исполнение промиса и назначение обработчика не будет происходить в «состоянии гонки», как, например, в случае с событиями в DOM.)
Так как методы {{JSxRef("Promise.then", "Promise.prototype.then()")}} и {{JSxRef("Promise.catch", "Promise.prototype.catch()")}} сами возвращают промис, их можно вызывать цепочкой, создавая соединения.

Примечание: говорят, что промис находится в состоянии завершён (settled) когда он или исполнен или отклонён, т.е. в любом состоянии, кроме ожидания (это лишь форма речи, не являющаяся настоящим состоянием промиса). Также можно встретить термин исполнен (resolved) — это значит что промис завершён или "заблокирован" в ожидании завершения другого промиса. В статье состояния и fates приводится более подробное описание терминологии.
Promise.lengthPromise.iterable. В случае, если любой из промисов будет отклонён, Promise.all будет также отклонён.iterable.reason.value.Если у value имеется метод then, то возвращаемый промис будет "следовать" продолжению, выступая адаптером его состояния; в противном случае будет возвращён промис в исполненном состоянии. Если вы не уверены, является ли некоторое значение промисом, вы можете обернуть его в {{JSxRef("Promise.resolve", "Promise.resolve(value)")}} и продолжить работу с ним как с промисом.
Объект Promise создаётся при помощи ключевого слова new и своего конструктора. Конструктор Promise принимает в качестве аргумента функцию, называемую "исполнитель" (executor function). Эта функция должна принимать две функции-колбэка в качестве параметров. Первый из них (resolve) вызывается, когда асинхронная операция завершилась успешно и вернула результат своего исполнения в виде значения. Второй колбэк (reject) вызывается, когда операция не удалась, и возвращает значение, указывающее на причину неудачи, чаще всего объект ошибки.
const myFirstPromise = new Promise((resolve, reject) => {
// выполняется асинхронная операция, которая в итоге вызовет:
//
// resolve(someValue); // успешное завершение
// или
// reject("failure reason"); // неудача
});
Чтобы снабдить функцию функциональностью промисов, нужно просто вернуть в ней объект Promise:
function myAsyncFunction(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}
Создать промис!
let myFirstPromise = new Promise((resolve, reject) => {
// Мы вызываем resolve(...), когда асинхронная операция завершилась успешно, и reject(...), когда она не удалась.
// В этом примере мы используем setTimeout(...), чтобы симулировать асинхронный код.
// В реальности вы, скорее всего, будете использовать XHR, HTML5 API или что-то подобное.
setTimeout(function(){
resolve("Success!"); // Ура! Всё прошло хорошо!
}, 250);
});
myFirstPromise.then((successMessage) => {
// successMessage - это что угодно, что мы передали в функцию resolve(...) выше.
// Это необязательно строка, но если это всего лишь сообщение об успешном завершении, это наверняка будет она.
console.log("Ура! " + successMessage);
});
Создать промис!
<button id="btn">Создать Promise!</button> <div id="log"></div>
Данный небольшой пример показывает механизм работы с Promise. Метод testPromise() вызывается при каждом нажатии на {{HTMLElement("button")}}. При этом создаётся промис, который успешно выполняется при помощи window.setTimeout, со значением 'result' в случайном интервале от 1 до 3-х секунд.
исполнение промиса протоколируется при помощи продолжения p1.then. Это показывает как синхронная часть метода отвязана от асинхронного завершения промиса.
var promiseCount = 0;
function testPromise() {
var thisPromiseCount = ++promiseCount;
var log = document.getElementById('log');
log.insertAdjacentHTML('beforeend', thisPromiseCount +
') Запуск (запуск синхронного кода)
');
// Создаём промис, возвращающее 'result' (по истечении 3-х секунд)
var p1 = new Promise(
// Функция разрешения позволяет завершить успешно или
// отклонить промис
function(resolve, reject) {
log.insertAdjacentHTML('beforeend', thisPromiseCount +
') Запуск промиса (запуск асинхронного кода)
');
// Это всего лишь пример асинхронности
window.setTimeout(
function() {
// Промис исполнен!
resolve(thisPromiseCount)
}, Math.random() * 2000 + 1000);
});
// Указываем, что сделать с исполненным промисом
p1.then(
// Записываем в протокол
function(val) {
log.insertAdjacentHTML('beforeend', val +
') Промис исполнен (асинхронный код завершён)
');
});
log.insertAdjacentHTML('beforeend', thisPromiseCount +
') Промис создан (синхронный код завершён)
');
}
if ("Promise" in window) {
btn = document.getElementById("btn");
btn.addEventListener("click",testPromise);
}
else {
log = document.getElementById('log');
log.innerHTML = "Live example not available as your browser doesn't support the Promise interface.";
}
if ("Promise" in window) {
let btn = document.getElementById("btn");
btn.addEventListener("click",testPromise);
} else {
log = document.getElementById('log');
log.innerHTML = "Демонстрация невозможна, поскольку ваш браузер не поддерживает интерфейс <code>Promise<code>.";
}
Данный пример запускается при нажатии на кнопку. Для этого вам необходим браузер, поддерживающий Promise. При последовательных нажатиях на кнопку с коротким интервалом, вы можете увидеть как различные промиса будут исполнены один за другим.
Другой простой пример использования Promise и XMLHttpRequest для загрузки изображения доступен в репозитории MDNpromise-test на GitHub. Вы также можете посмотреть его в действии. Каждый шаг прокомментирован и вы можете подробно исследовать Promise и XHR.
{{Compat}}