--- title: Promise slug: Web/JavaScript/Reference/Global_Objects/Promise tags: - ECMAScript 2015 - JavaScript - Promise translation_of: Web/JavaScript/Reference/Global_Objects/Promise ---
Об'єкт Promise
відображає остаточне завершення (або неуспіх) асинхронної операції та значення, яке вона повертає.
Щоб дізнатись, як працюють проміси та як їх можна використовувати, радимо вам спочатку прочитати статтю Використання промісів.
Promise
- це проксі для значення, яке може бути невідомим на момент створення проміса. Це дозволяє зв'язувати обробники з кінцевим успішним значенням чи причиною неуспіху асинхронних дій. Таким чином, асинхронні методи повертають значення, як синхронні методи: замість того, щоб негайно повернути кінцеве значення, асинхронний метод повертає проміс, щоб надати значення в певний момент у майбутньому.
Об'єкт Promise
може знаходитись в одному з цих станів:
Проміс у стані очікування може стати або виконаним (fulfilled) з певним значенням, або відхиленим (rejected) з причиною відхилення (помилкою). Коли щось із цього відбувається, викликаються відповідні обробники, що ставляться в чергу методом об'єкта then
. (Якщо проміс вже був виконаний чи відхилений ще до моменту приєднання відповідного обробника, то обробник буде викликаний, таким чином не відбувається "стану гонки" між завершенням асинхронної операції та приєднанням її обробників)
Оскільки методи {{jsxref("Promise.then", "Promise.prototype.then()")}}
та {{jsxref("Promise.catch", "Promise.prototype.catch()")}}
повертають проміси, їх можна з'єднувати в ланцюжки.
Не варто плутати з: Декілька інших мов мають механізми лінивих обчислень та відкладених розрахунків, які також називаються "promises" - наприклад, Scheme. Проміси у JavaScript відображають процеси, які вже відбуваються і які можуть бути з'єднані в ланцюги з функціями зворотного виклику. Якщо вам потрібне ліниве обчислення виразу, розгляньте стрілкові функції без аргументів: f = () => вираз
для створення лінивого виразу, та f()
для обчислення.
Заувага: Проміс називають встановленим (settled), якщо він або виконаний, або відхилений, але не знаходиться у стані очікування. Ви також почуєте термін вирішений (resolved) щодо промісів - він означає, що проміс встановлений, або ж "зафіксований", щоб відповідати стану іншого проміса. Стаття States and Fates містить більше подробиць щодо термінології промісів.
Promise()
Promise.length
Promise.prototype
Promise
.Promise
, відхилений з наданою причиною.Promise
, який вирішується з наданим значенням. Якщо значенням є промісоподібний об'єкт (такий, що має метод then
), то повернений проміс буде його "дотримуватись", приймаючи його кінцевий стан; у іншому випадку повернений проміс буде виконаний з наданим значенням.Promise.prototype.constructor
onFulfilled
чи onRejected
не є функцією).let myFirstPromise = new Promise((resolve, reject) => { // Викликаємо resolve(...), коли те, що ми робили асинхронно, успішно виконалось, і reject(...), якщо неуспішно. // В цьому прикладі ми використовуємо setTimeout(...) для симуляції асинхронного коду. // В житті ви, ймовірно, використовуватиме щось на кшталт XHR або HTML5 API. setTimeout( function() { resolve("Успіх!") // Є! Все пройшло добре! }, 250) }) myFirstPromise.then((successMessage) => { // successMessage - це те, що ми передаємо у наведену вище функцію resolve(...). // Це не обов'язково має бути рядок, але, якщо це повідомлення про успіх, то, мабуть, це буде він. console.log("Є! " + successMessage) });
<button id="btn">Зробити проміс!</button> <div id="log"></div>
Цей маленький приклад демонструє механізм об'єкта Promise
. Метод testPromise()
викликається кожний раз, коли натискається кнопка <button>
. Він створює проміс, який буде виконаний з використанням window.setTimeout()
з лічильником проміса (число, що стартує від 1) кожні 1-3 секунди, у випадковому порядку. Конструктор Promise()
використовується для створення проміса.
Виконання проміса логується просто, виконанням зворотного виклику через {{jsxref("Promise.prototype.then()","p1.then()")}}. Кілька логів демонструють, як синхронна частина методу відокремлюється від асинхронного завершення проміса.
'use strict'; var promiseCount = 0; function testPromise() { var thisPromiseCount = ++promiseCount; var log = document.getElementById('log'); log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Запуск (<small>Синхронний код запущено</small>)<br/>'); // Створюємо новий проміс: ми передаємо лічильник цього проміса, починаючи з 1 (після очікування 3с) var p1 = new Promise( // Функція вирішення викликається з можливістю вирішити або // відхилити проміс function(resolve, reject) { log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Запуск проміса (<small>Асинхронний код запущено</small>)<br/>'); // Це лише приклад для створення асинхронності window.setTimeout( function() { // Ми виконуємо проміс! resolve(thisPromiseCount); }, Math.random() * 2000 + 1000); } ); // Визначаємо, що робити, коли проміс вирішено/виконано, викликом then(), // а метод catch() визначає, що робити, якщо проміс відхилено. p1.then( // Залогувати значення виконання function(val) { log.insertAdjacentHTML('beforeend', val + ') Проміс виконано (<small>Асинхронний код завершений</small>)<br/>'); }) .catch( // Залогувати причину відхилення function(reason) { console.log('Обробити тут відхилений проміс ('+reason+').'); }); log.insertAdjacentHTML('beforeend', thisPromiseCount + ') Проміс створено (<small>Синхронний код завершений</small>)<br/>'); }
if ("Promise" in window) { var btn = document.getElementById("btn"); btn.addEventListener("click",testPromise); } else { log = document.getElementById('log'); log.innerHTML = "Живий приклад недоступний, оскільки ваш переглядач не підтримує інтерфейс об'єктів <code>Promise<code>."; }
Цей приклад починається натисканням кнопки. Вам потрібен переглядач, що підтримує об'єкти Promise
. Натиснувши кнопку кілька разів за короткий відрізок часу, ви навіть побачите, як різні проміси виконуються один після іншого.
{{EmbedLiveSample("Ускладнений_приклад", "500", "200")}}
Інший простий приклад використання об'єктів Promise
та XMLHttpRequest
- для завантаження зображення - доступний у репозиторії promise-test на MDN GitHub. Ви також можете побачити його в дії. Кожний крок супроводжується коментарями та дозволяє відслідкувати архітектуру Promise та XHR.
Specification |
---|
{{SpecName('ESDraft', '#sec-promise-objects', 'Promise')}} |
To contribute to this compatibility data, please write a pull request against this file: https://github.com/mdn/browser-compat-data.
{{Compat("javascript.builtins.Promise")}}