aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/reference/global_objects/promise/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/ru/web/javascript/reference/global_objects/promise/index.html')
-rw-r--r--files/ru/web/javascript/reference/global_objects/promise/index.html267
1 files changed, 267 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/global_objects/promise/index.html b/files/ru/web/javascript/reference/global_objects/promise/index.html
new file mode 100644
index 0000000000..c4577ab151
--- /dev/null
+++ b/files/ru/web/javascript/reference/global_objects/promise/index.html
@@ -0,0 +1,267 @@
+---
+title: Promise
+slug: Web/JavaScript/Reference/Global_Objects/Promise
+tags:
+ - ECMAScript6
+ - JavaScript
+ - Promise
+ - Обещания
+translation_of: Web/JavaScript/Reference/Global_Objects/Promise
+---
+<div>{{JSRef}}</div>
+
+<h2 id="Сводка">Сводка</h2>
+
+<p>Объект <strong><code>Promise</code></strong> (промис) используется для отложенных и асинхронных вычислений.</p>
+
+<p>{{EmbedInteractiveExample("pages/js/promise-constructor.html")}}</p>
+
+<div class="hidden">
+<p>Исходники интерактивного демо находятся в репозитории на GitHub. Если вы хотите внести свой вклад в развитие интерактивных демо, пожалуйста, склонируйте <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> и отправьте нам пулреквест.</p>
+</div>
+
+<h2 id="Синтаксис">Синтаксис</h2>
+
+<pre class="brush: js">new Promise(<em>executor</em>);
+new Promise(function(resolve, reject) { ... });</pre>
+
+<h3 id="Параметры">Параметры</h3>
+
+<dl>
+ <dt>executor</dt>
+ <dd>Объект функции с двумя аргументами <code>resolve</code> и <code>reject</code>. Функция <code>executor</code>  получает оба аргумента и выполняется сразу, еще до того как конструктор вернет созданный объект. Первый аргумент (<code>resolve</code>) вызывает успешное исполнение промиса, второй (<code>reject</code>) отклоняет его.<br>
+ Обычно функция <code>executor</code> описывает выполнение какой-то асинхронной работы, по завершении которой необходимо вызвать функцию <code>resolve</code> или <code>reject</code>. Обратите внимание, что возвращаемое значение функции <code>executor</code> игнорируется.</dd>
+</dl>
+
+<h2 id="Описание">Описание</h2>
+
+<p>Интерфейс <code><strong>Promise</strong></code> (промис) представляет собой обертку для значения, неизвестного на момент создания промиса. Он позволяет обрабатывать результаты асинхронных операций так, как если бы они были синхронными: вместо конечного результата асинхронного метода возвращается <em>обещание </em>(промис)<em> </em>получить результат в некоторый момент в будущем.</p>
+
+<p><code>Promise</code> может находиться в трёх состояниях:</p>
+
+<ul>
+ <li><em>ожидание (pending)</em>: начальное состояние, не исполнен и не отклонен.</li>
+ <li><em>исполнено (fulfilled)</em>: операция завершена успешно.</li>
+ <li><em>отклонено (rejected)</em>: операция завершена с ошибкой.</li>
+</ul>
+
+<p>При создании промис находится в <em>ожидании (pending)</em>, а затем может стать <em>исполненным </em> (<em>fulfilled)</em>, вернув полученный результат (значение), или <em>отклоненным </em>(<em>rejected),</em> вернув причину отказа. В любом из этих случаев вызывается обработчик, прикрепленный к промису методом <code>then</code>. (Если в момент назначения обработчика промис уже исполнен или отклонен, обработчик все равно будет вызван, т.е. асинхронное исполнение промиса и назначение обработчика не будет происходить в «состоянии гонки», как, например, в случае с событиями в DOM.)</p>
+
+<p>Так как методы <code>{{JSxRef("Promise.then", "Promise.prototype.then()")}}</code> и <code>{{JSxRef("Promise.catch", "Promise.prototype.catch()")}}</code> сами возвращают промис, их можно вызывать цепочкой, создавая <em>соединения.</em></p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/8633/promises.png" style="height: 297px; width: 801px;"></p>
+
+<div class="blockIndicator note">
+<p><strong>Примечание:</strong> говорят, что промис находится в состоянии <em>завершен (settled) </em>когда он или исполнен или отклонен, т.е. в любом состоянии, кроме ожидания (это лишь форма речи, не являющаяся настоящим состоянием промиса). Также можно встретить термин <em>исполен (resolved) </em>— это значит что промис <em>завершен </em>или "заблокирован" в ожидании завершения другого промиса. В статье <a href="https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md">состояния и fates</a> приводится более подробное описание терминологии.</p>
+</div>
+
+<h2 id="Свойства">Свойства</h2>
+
+<dl>
+ <dt><code>Promise.length</code></dt>
+ <dd>Значение свойства всегда равно 1 (количество аргументов конструктора).</dd>
+ <dt>{{jsxref("Promise.prototype")}}</dt>
+ <dd>Представляет прототип для конструктора <code>Promise</code>.</dd>
+</dl>
+
+<h2 id="Методы">Методы</h2>
+
+<dl>
+ <dt>{{jsxref("Promise.all", "Promise.all(iterable)")}}</dt>
+ <dd>Ожидает исполнения всех промисов или отклонения любого из них.</dd>
+ <dd>Возвращает промис, который исполнится после исполнения всех промисов в <code>iterable</code>. В случае, если любой из промисов будет отклонен, <code>Promise.all</code> будет также отклонен.</dd>
+ <dt>{{JSxRef("Promise.allSettled", "Promise.allSettled(iterable)")}}</dt>
+ <dd>Ожидает завершения всех полученных промисов (как исполнения так и отклонения).</dd>
+ <dd>Возвращает промис, который исполняется когда все полученные промисы завершены (исполнены или отклонены), содержащий массив результатов исполнения полученных промисов.</dd>
+ <dt>{{jsxref("Promise.race", "Promise.race(iterable)")}}</dt>
+ <dd>Ожидает исполнения или отклонения любого из полученных промисов.</dd>
+ <dd>Возвращает промис, который будет исполнен или отклонен с результатом исполнения первого исполненного или отклонённого промиса из .<code>iterable</code>.</dd>
+</dl>
+
+<dl>
+ <dt>{{jsxref("Promise.reject", "Promise.reject(reason)")}}</dt>
+ <dd>Возвращает промис, отклонённый из-за <code>reason</code>.</dd>
+</dl>
+
+<dl>
+ <dt>{{jsxref("Promise.resolve", "Promise.resolve(value)")}}</dt>
+ <dd>Возвращает промис, исполненный с результатом <code>value</code>.</dd>
+ <dd>
+ <div class="hidden">
+ <p>Если у <code>value</code> имеется метод <code>then</code>, то возвращаемый промис будет "следовать" продолжению, выступая адаптером его состояния; в противном случае будет возвращен промис в исполненном состоянии. Если вы не уверены, является ли некоторое значение промисом, вы можете обернуть его в  {{JSxRef("Promise.resolve", "Promise.resolve(value)")}} и продолжить работу с ним как с промисом.</p>
+ </div>
+ </dd>
+</dl>
+
+<h2 id="Прототип_Promise">Прототип <code>Promise</code></h2>
+
+<h3 id="Свойства_2">Свойства</h3>
+
+<p>{{page('ru/docs/Web/JavaScript/Reference/Global_Objects/Promise/prototype','Свойства')}}</p>
+
+<h3 id="Методы_2">Методы</h3>
+
+<p>{{page('ru/docs/Web/JavaScript/Reference/Global_Objects/Promise/prototype','Методы')}}</p>
+
+<h2 id="Создание_промиса">Создание промиса</h2>
+
+<p>Объект <code>Promise</code> создается при помощи ключевого слова <code>new</code> и своего конструктора. Конструктор <code>Promise</code> принимает в качестве аргумента функцию, называемую "исполнитель" (<em>executor function</em>). Эта функция должна принимать две функции-коллбэка в качестве параметров. Первый из них (<code>resolve</code>) вызывается, когда асинхронная операция завершилась успешно и вернула результат своего исполнения в виде значения. Второй коллбэк (<code>reject</code>) вызывается, когда операция не удалась, и возвращает значение, указывающее на причину неудачи, чаще всего объект ошибки.</p>
+
+<pre class="brush: js">const myFirstPromise = new Promise((resolve, reject) =&gt; {
+ // выполняется асинхронная операция, которая в итоге вызовет:
+ //
+ // resolve(someValue); // успешное завершение
+ // или
+ // reject("failure reason"); // неудача
+});</pre>
+
+<p>Чтобы снабдить функцию функционалом обещаний, нужно просто вернуть в ней объект <code>Promise</code>:</p>
+
+<pre class="brush: js">function myAsyncFunction(url) {
+ return new Promise((resolve, reject) =&gt; {
+ const xhr = new XMLHttpRequest();
+ xhr.open("GET", url);
+ xhr.onload = () =&gt; resolve(xhr.responseText);
+ xhr.onerror = () =&gt; reject(xhr.statusText);
+ xhr.send();
+ });
+}</pre>
+
+<h2 id="Примеры">Примеры</h2>
+
+<h3 id="Простой_пример">Простой пример</h3>
+
+<pre class="brush: html" style="display: none;">Создать промис!
+</pre>
+
+<pre class="brush: js">let myFirstPromise = new Promise((resolve, reject) =&gt; {
+ // Мы вызываем resolve(...), когда асинхронная операция завершилась успешно, и reject(...), когда она не удалась.
+ // В этом примере мы используем setTimeout(...), чтобы симулировать асинхронный код.
+ // В реальности вы, скорее всего, будете использовать XHR, HTML5 API или что-то подобное.
+ setTimeout(function(){
+ resolve("Success!"); // Ура! Всё прошло хорошо!
+ }, 250);
+});
+
+myFirstPromise.then((successMessage) =&gt; {
+ // successMessage - это что угодно, что мы передали в функцию resolve(...) выше.
+ // Это необязательно строка, но если это всего лишь сообщение об успешном завершении, это наверняка будет она.
+ console.log("Ура! " + successMessage);
+});</pre>
+
+<h3 id="Продвинутый_пример">Продвинутый пример</h3>
+
+<pre class="brush: html" style="display: none;">Создать промис!
+</pre>
+
+<div id="log">
+<pre class="brush: html">&lt;button id="btn"&gt;Создать Promise!&lt;/button&gt;
+&lt;div id="log"&gt;&lt;/div&gt;</pre>
+</div>
+
+<p>Данный небольшой пример показывает механизм работы с <code>Promise</code>. Метод <code>testPromise()</code> вызывается при каждом нажатии на {{HTMLElement("button")}}. При этом создаётся промис, которое успешно выполняется при помощи <code>window.setTimeout</code>, со значением <code>'result'</code> в случайном интервале от 1 до 3-х секунд.</p>
+
+<p>исполнение промиса протоколируется при помощи продолжения <code>p1.then</code>. Это показывает как синхронная часть метода отвязана от асинхронного завершения промиса.</p>
+
+<pre class="brush: js">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 +
+ ') Обещание создано (синхронный код завершён)
+');
+}
+</pre>
+
+<pre class="brush:js" style="display: none;">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.";
+}
+</pre>
+
+<pre class="brush: js">if ("Promise" in window) {
+ let btn = document.getElementById("btn");
+ btn.addEventListener("click",testPromise);
+} else {
+ log = document.getElementById('log');
+ log.innerHTML = "Демонстрация невозможна, поскольку ваш браузер не поддерживает интерфейс &lt;code&gt;Promise&lt;code&gt;.";
+}</pre>
+
+<p>Данный пример запускается при нажатии на кнопку. Для этого вам необходим браузер, поддерживающий <code>Promise</code>. При последовательных нажатиях на кнопку с коротким интервалом, вы можете увидеть как различные промиса будут исполнены один за другим.</p>
+
+<h3 id="Загрузка_изображения_при_помощи_XHR">Загрузка изображения при помощи XHR</h3>
+
+<p>Другой простой пример использования <code>Promise</code> и <code><a href="/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a></code> для загрузки изображения доступен в репозитории MDN<a href="https://github.com/mdn/js-examples/tree/master/promises-test">promise-test</a> на GitHub. Вы также можете <a href="https://mdn.github.io/js-examples/promises-test/">посмотреть его в действии</a>. Каждый шаг прокомментирован и вы можете подробно исследовать Promise и XHR.</p>
+
+<h2 id="Спецификации">Спецификации</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Спецификация</th>
+ <th scope="col">Статус</th>
+ <th scope="col">Комментарий</th>
+ </tr>
+ <tr>
+ <td><a href="https://github.com/domenic/promises-unwrapping">domenic/promises-unwrapping</a></td>
+ <td>Черновик</td>
+ <td>Начало работы над стандартом.</td>
+ </tr>
+ <tr>
+ <td>{{SpecName('ES6', '#sec-promise-objects', 'Promise')}}</td>
+ <td>{{Spec2('ES6')}}</td>
+ <td>Изначальное определение в стандарте ECMA.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2>
+
+<p>{{Compat("javascript.builtins.Promise")}}</p>
+
+<h2 id="Смотрите_также">Смотрите также</h2>
+
+<ul>
+ <li><a href="http://promisesaplus.com/">Спецификация Promises/A+</a></li>
+ <li><a href="http://www.html5rocks.com/en/tutorials/es6/promises/">Jake Archibald: JavaScript Promises: There and Back Again</a></li>
+ <li><a href="http://de.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript">Domenic Denicola: Callbacks, Promises, and Coroutines – Asynchronous Programming Pattern in JavaScript</a></li>
+ <li><a href="http://www.mattgreer.org/articles/promises-in-wicked-detail/">Matt Greer: JavaScript Promises ... In Wicked Detail</a></li>
+ <li><a href="https://www.promisejs.org/">Forbes Lindesay: promisejs.org</a></li>
+ <li><a href="http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html">Nolan Lawson: We have a problem with promises — Common mistakes with promises</a></li>
+ <li><a href="https://github.com/jakearchibald/es6-promise/">Promise polyfill</a></li>
+ <li><a href="https://www.udacity.com/course/javascript-promises--ud898">Udacity: JavaScript Promises</a></li>
+</ul>