Promise

Сводка

Объект Promise (обещание) используется для отложенных и асинхронных вычислений. Promise может находиться в трёх состояниях:

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

Другой термин, описывающий состояние заданный (settled): обещание выполнено или отклонено, но не находится в состоянии ожидания.

Синтаксис

new Promise(executor);
new Promise(function(resolve, reject) { ... });

Параметры

executor
Объект функции с двумя аргументами resolve и reject. Первый аргумент вызывает успешное выполнение обещания, второй отклоняет его. Мы можем вызывать эти функции по завершении нашей операции.

Описание

Интерфейс Promise (обещание) представляет собой обертку для значения, неизвестного на момент создания обещания. Он позволяет обрабатывать результаты асинхронных операций так, как если бы они были синхронными: вместо конечного результата асинхронного метода возвращается обещание получить результат в некоторый момент в будущем.

При создании обещание находится в ожидании (pending), а затем может стать выполнено  (fulfilled), вернув полученный результат (значение), или отклонено (rejected), вернув причину отказа. В любом из этих случаев вызывается обработчик, прикрепленный к обещанию методом then . Если в момент прикрепления обработчика обещание уже сдержано или нарушено, он все равно будет выполнен, т.е. между выполнением обещания и прикреплением обработчика нет «состояния гонки», как, например, в случае с событиями в DOM.

Так как методы Promise.prototype.then и Promise.prototype.catch сами возвращают обещания, их можно вызывать цепочкой, создавая соединения.

Свойства

Promise.length
Значение свойства всегда равно 1 (количество аргументов конструктора).
Promise.prototype
Представляет прототип для конструктора Promise.

Методы

Promise.all(iterable)
Возвращает обещание, которое выполнится после выполнения всех обещаний в передаваемом итерируемом аргументе.
Promise.race(iterable)
Возвращает обещание, которое будет выполнено или отклонено с результатом исполнения первого выполненного или отклонённого итерируемого обещания.
Promise.reject(reason)
Возвращает объект Promise, который отклонён с указанной причиной.
Promise.resolve(value)
Возвращает объект Promise, который выполнен с указанным значением. Если значение может быть продолжено (имеется метод then), то возвращаемое обещание будет "следовать" продолжению, выступая адаптером его состояния; в противном случае будет возвращено ожидание в выполненном состоянии.

Прототип Promise

Свойства

Promise.prototype.constructor
Возвращает функцию, которая создала прототип экземпляра. Это функция всех обещаний по умолчанию.

Методы

Promise.prototype.catch(onRejected)
Добавляет функцию обратного вызова, для обработки отклонения обещания, которая возвращает новое обещание выполненное с переданным значением, если она вызвана, или оригинальное значение resolve, если обещание выполнено.
Promise.prototype.then(onFulfilled, onRejected)
Добавляет обработчик выполнения и отклонения обещания, и возвращает новое обещание выполненное со значением вызванного обработчика, или оригинальное значение, если обещание не было обработано (т.е. если соответствующий обработчик onFulfilled или onRejected не является функцией).

Примеры

Создание обещания

 

Данный небольшой пример показывает механизм работы с Promise. Метод testPromise() вызывается при каждом нажатии на <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 + 
      ') Обещание создано (синхронный код завершён)
');
}

Данный пример запускается при нажатии на кнопку. Для этого вам необходим браузер, поддерживающий Promise. При последовательных нажатиях на кнопку с коротким интервалом, вы можете увидеть как различные обещания будут выполнены один за другим.

Загрузка изображения при помощи XHR

Другой простой пример использования Promise и XMLHttpRequest для загрузки изображения доступен в репозитории MDN promise-test на GitHub. Вы также можете посмотреть его в действии. Каждый шаг прокомментирован и вы можете подробно исследовать Promise и XHR.

Спецификации

Спецификация Статус Комментарий
domenic/promises-unwrapping Черновик Начало работы над стандартом.
ECMAScript 2015 (6th Edition, ECMA-262)
Определение 'Promise' в этой спецификации.
Стандарт Изначальное определение в стандарте ECMA.

Совместимость с браузерами

Возможность Chrome Firefox (Gecko) Internet Explorer Opera Safari
Базовая поддержка 32 24.0 (24.0) как Future
25.0 (25.0) как Promise при наличии флага[1]
29.0 (29.0) по умолчанию
Нет 19 7.1
Возможность Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile Chrome for Android
Базовая поддержка Нет 24.0 (24.0) как Future
25.0 (25.0) как Promise при наличии флага[1]
29.0 (29.0) по умолчанию
Нет Нет iOS 8 32

[1] В Gecko 24 есть экспериментальная реализация Promise под предварительным именем Future. В Gecko 25 ей дано текущее название, но её поддержка по умолчанию отключена, за это отвечает флаг dom.promise.enabled. После исправления Bug 918806 в Gecko 29 обещания работают по умолчанию.

Смотрите также

Метки документа и участники

 Внесли вклад в эту страницу: RinatMullayanov, AlexKhram, applicab, prettyGoo, dtretyakov, Chudesnov
 Обновлялась последний раз: RinatMullayanov,