diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:43:23 -0500 |
commit | 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 (patch) | |
tree | a9ef8ac1e1b8fe4207b6d64d3841bfb8990b6fd0 /files/uk/web/javascript/reference/global_objects/promise/then/index.html | |
parent | 074785cea106179cb3305637055ab0a009ca74f2 (diff) | |
download | translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.gz translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.tar.bz2 translated-content-218934fa2ed1c702a6d3923d2aa2cc6b43c48684.zip |
initial commit
Diffstat (limited to 'files/uk/web/javascript/reference/global_objects/promise/then/index.html')
-rw-r--r-- | files/uk/web/javascript/reference/global_objects/promise/then/index.html | 297 |
1 files changed, 297 insertions, 0 deletions
diff --git a/files/uk/web/javascript/reference/global_objects/promise/then/index.html b/files/uk/web/javascript/reference/global_objects/promise/then/index.html new file mode 100644 index 0000000000..8cbcc884fc --- /dev/null +++ b/files/uk/web/javascript/reference/global_objects/promise/then/index.html @@ -0,0 +1,297 @@ +--- +title: Promise.prototype.then() +slug: Web/JavaScript/Reference/Global_Objects/Promise/then +tags: + - ECMAScript 2015 + - JavaScript + - Promise + - метод +translation_of: Web/JavaScript/Reference/Global_Objects/Promise/then +--- +<div>{{JSRef}}</div> + +<p>Метод <code><strong>then()</strong></code> вертає об'єкт {{jsxref("Promise")}}. Він приймає два аргументи: функції зворотного виклику для випадків успішного та неуспішного проміса.</p> + +<div>{{EmbedInteractiveExample("pages/js/promise-then.html")}}</div> + +<p class="hidden">The source for this interactive demo is stored in a GitHub repository. If you'd like to contribute to the interactive demo project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</p> + +<div class="note"> +<p>Якщо один чи обидва аргументи пропущені, або надані не функції, тоді <code>then</code> не матиме обробників, але не згенерує помилок. Якщо <code>Promise</code>, на якому викликається <code>then</code>, приймає стан (<code>виконання</code> або <code>відхилення</code>), для якого <code>then</code> не має обробника, новий <code>Promise</code> створюється без додаткових обробників, просто приймаючи кінцевий стан оригінального проміса, на якому було викликано <code>then</code>.</p> +</div> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox"><var>p.then(onFulfilled[, onRejected])</var>; + +p.then(value => { + // виконання +}, reason => { + // відхилення +}); +</pre> + +<h3 id="Параметри">Параметри</h3> + +<dl> + <dt><code>onFulfilled</code> {{optional_inline}}</dt> + <dd>{{jsxref("Function","Функція")}}, що викликається, якщо <code>Promise</code> виконано. Ця функція має один аргумент, <code>значення виконання</code>. Якщо це не функція, вона внутрішньо замінюється на функцію "Identity" (вона повертає отриманий аргумент).</dd> + <dt><code>onRejected</code> {{optional_inline}}</dt> + <dd>{{jsxref("Function","Функція")}}, що викликається, якщо <code>Promise</code> відхилено. Ця функція має один аргумент, <code>причина відхилення</code>. Якщо це не функція, вона внутрішньо замінюється на функцію "Thrower" (вона викидає помилку, яку отримала в якості аргумента).</dd> +</dl> + +<h3 id="Значення_що_повертається">Значення, що повертається</h3> + +<p>Як тільки {{jsxref("Promise","проміс")}} був виконаний або відхилений, відповідна функція-обробник (<code style="font-style: normal; font-weight: normal;">onFulfilled</code> або <code style="font-style: normal; font-weight: normal;">onRejected</code>) буде викликана <strong>асинхронно</strong> (запланована у активному циклі потоку). Поведінка функції-обробника відповідає спеціальному набору правил. Якщо функція-обробник:</p> + +<ul> + <li>вертає значення, проміс, повернений <code>then</code>, вирішується з поверненим значенням в якості його значення.</li> + <li>не вертає нічого, проміс, повернений <code>then</code>, вирішується зі значенням <code>undefined</code>.</li> + <li>викидає помилку, проміс, повернений <code>then</code>, відхиляється з викинутою помилкою в якості значення.</li> + <li>вертає вже виконаний проміс, то проміс, повернений <code>then</code>, виконується зі значенням цього проміса в якості свого значення.</li> + <li>вертає вже відхилений проміс, то проміс, повернений <code>then</code>, відхиляється зі значенням цього проміса в якості свого значення.</li> + <li>вертає інший проміс <strong>у стані очікування</strong>, вирішення/відхилення проміса, поверненого <code>then</code>, буде результатом вирішення/відхилення проміса, поверненого обробником. Також, вирішене значення проміса, поверненого <code>then</code>, буде тим самим, що й вирішене значення проміса, поверненого обробником.</li> +</ul> + +<p>Наступний приклад демонструє асинхронність методу <code>then</code>.</p> + +<pre class="brush: js">// при використанні вирішеного проміса блок 'then' буде негайно запущений, +// але його обробники запустяться асинхронно, як демонструє console.log +const resolvedProm = Promise.resolve(33); + +let thenProm = resolvedProm.then(value => { + console.log("Це запускається після завершення головного стеку. Отримане й повернене значення: " + value); + return value; +}); +// негайне логування значення thenProm +console.log(thenProm); + +// використовуючи setTimeout, ми можемо відкласти виконання функції, поки стек не стане порожнім +setTimeout(() => { + console.log(thenProm); +}); + + +// порядок логування: +// Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined} +// "Це запускається після завершення головного стеку. Отримане й повернене значення: 33" +// Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 33}</pre> + +<h2 id="Опис">Опис</h2> + +<p>Оскільки методи <code>then</code> та {{jsxref("Promise.prototype.catch()")}} вертають проміси, їх <a href="/uk/docs/Web/JavaScript/Guide/Using_promises#Chaining">можна поєднувати в ланцюги</a> — ця операція зветься <em>композицією</em>.</p> + +<h2 id="Приклади">Приклади</h2> + +<h3 id="Використання_метода_then">Використання метода <code>then</code></h3> + +<pre class="brush: js">var p1 = new Promise((resolve, reject) => { + resolve('Успіх!'); + // або + // reject(new Error("Помилка!")); +}); + +p1.then(value => { + console.log(value); // Успіх! +}, reason => { + console.error(reason); // Помилка! +}); +</pre> + +<h3 id="Ланцюгування">Ланцюгування</h3> + +<p>Метод <code>then</code> вертає об'єкт <code>Promise</code>, що дозволяє використовувати ланцюгування.</p> + +<p>Якщо функція, передана у <code>then</code> в якості обробника, вертає об'єкт <code>Promise</code>, аналогічний об'єкт <code>Promise</code> буде переданий у наступний <code>then</code> ланцюга методів. Наведений нижче фрагмент імітує асинхронний код функцією <code>setTimeout</code>. </p> + +<pre class="brush: js">Promise.resolve('ква') + // 1. Отримати "ква", приєднати "драт" та вирішити це для наступного then + .then(function(string) { + return new Promise(function(resolve, reject) { + setTimeout(function() { + string += 'драт'; + resolve(string); + }, 1); + }); + }) + // 2. отримати "квадрат", призначити функцію зворотного виклику для обробки цього рядка + // та вивести його на консоль, але не раніше повернення необробленого рядка + // string у наступний then + .then(function(string) { + setTimeout(function() { + string += 'ура'; + console.log(string); + }, 1) + return string; + }) + // 3. вивести допоміжні повідомлення щодо того, як виконується код в цьому розділі, + // раніше, ніж рядок string буде оброблений імітованим асинхронним кодом у + // попередньому блоці then. + .then(function(string) { + console.log("Останній Then: йой... ми не створили та не повернули екземпляр проміса " + + "у попередньому then, тому послідовність може бути трохи " + + "несподіваною"); + + // Зауважте, що `string` не матиме частини 'ура' в цій точці. Це тому, + // що ми імітували його асинхронне виконання за допомогою функції setTimeout + console.log(string); + }); + +// порядок виведення: +// Останній Then: йой... ми не створили та не повернули екземпляр проміса у попередньому then, тому послідовність може бути трохи несподіваною +// квадрат +// квадратура</pre> + +<p>Коли значення просто повертається з обробника <code>then</code>, він поверне <code>Promise.resolve(<значення, повернене обробником, що викликався>)</code>.</p> + +<pre class="brush: js">var p2 = new Promise(function(resolve, reject) { + resolve(1); +}); + +p2.then(function(value) { + console.log(value); // 1 + return value + 1; +}).then(function(value) { + console.log(value + ' - Синхронне значення працює'); +}); + +p2.then(function(value) { + console.log(value); // 1 +}); +</pre> + +<p>Виклик <code>then</code> поверне відхилений проміс, якщо функція викидає помилку або повертає відхилений проміс.</p> + +<pre class="brush: js">Promise.resolve() + .then(() => { + // Змушує .then() повернути відхилений проміс + throw new Error('О, ні!'); + }) + .then(() => { + console.log('Не викликається.'); + }, error => { + console.error('Викликано функцію onRejected: ' + error.message); + });</pre> + +<p>У всіх інших випадках повертається вирішений об'єкт Promise. У наступному прикладі перший <code>then()</code> поверне значення <code>42</code>, загорнуте у вирішений проміс, незважаючи на те, що попередній проміс ланцюжка був відхилений.</p> + +<pre class="brush: js">Promise.reject() + .then(() => 99, () => 42) // onRejected вертає 42, обгорнуте у вирішений Promise + .then(solution => console.log('Вирішений зі значенням ' + solution)); // Вирішений зі значенням 42</pre> + +<p>На практиці часто бажано перехоплювати відхилені проміси, як продемонстровано нижче, а не використовувати синтаксис <code>then</code> для двох випадків.</p> + +<pre class="brush: js">Promise.resolve() + .then(() => { + // Змушує .then() повернути відхилений проміс + throw new Error('О, ні!'); + }) + .catch(error => { + console.error('Викликано функцію onRejected: ' + error.message); + }) + .then(() => { + console.log("Мене завжди викликають, навіть якщо проміс попереднього then відхилено"); + });</pre> + +<p>Ви також можете використати ланцюгування, щоб реалізувати функцію з API на промісах, на основі іншої такої функції.</p> + +<pre class="brush: js">function fetch_current_data() { + // API <a href="/uk/docs/Web/API/GlobalFetch/fetch">fetch</a>() вертає проміс. Ця функція + // створює схожий API, крім того, що над значенням + // виконанного проміса цієї функції виконується + // більше дій. + return fetch('current-data.json').then(response => { + if (response.headers.get('content-type') != 'application/json') { + throw new TypeError(); + } + var j = response.json(); + // можливо, зробити щось із j + return j; // значення виконання, що надається користувачу + // fetch_current_data().then() + }); +} +</pre> + +<p>Якщо <code>onFulfilled</code> вертає проміс, повернене значення <code>then</code> буде вирішене чи відхилене промісом.</p> + +<pre class="brush: js">function resolveLater(resolve, reject) { + setTimeout(function() { + resolve(10); + }, 1000); +} +function rejectLater(resolve, reject) { + setTimeout(function() { + reject(new Error('Помилка')); + }, 1000); +} + +var p1 = Promise.resolve('ква'); +var p2 = p1.then(function() { + // Повернути тут проміс, який буде вирішений зі значенням 10 через 1 секунду + return new Promise(resolveLater); +}); +p2.then(function(v) { + console.log('вирішений', v); // "вирішений", 10 +}, function(e) { + // не викликається + console.error('відхилений', e); +}); + +var p3 = p1.then(function() { + // Повернути тут проміс, що відхилятиметься з помилкою 'Помилка' через 1 секунду + return new Promise(rejectLater); +}); +p3.then(function(v) { + // не викликається + console.log('вирішений', v); +}, function(e) { + console.error('відхилений', e); // "відхилений", 'Помилка' +}); +</pre> + +<h3 id="Поліфіл_у_стилі_window.setImmediate_на_основі_промісів">Поліфіл у стилі <a href="/uk/docs/Web/API/Window/setImmediate" title="Цей метод використовується для розбиття довгих у виконанні операцій та запуску функції зворотного виклику негайно після того, як переглядач завершив інші операції, такі, як події та оновлення відображення">window.setImmediate</a> на основі промісів</h3> + +<p>Використання методу {{jsxref("Function.prototype.bind()")}} <code>Reflect.apply</code> ({{jsxref("Reflect.apply()")}}) для створення функції (що не скасовується) у стилі setImmediate.</p> + +<pre class="brush: js">const nextTick = (() => { + const noop = () => {}; // буквально + const nextTickPromise = () => Promise.resolve().then(noop); + + const rfab = Reflect.apply.bind; // (thisArg, fn, thisArg, [...args]) + const nextTick = (fn, ...args) => ( + fn !== undefined + ? Promise.resolve(args).then(rfab(null, fn, null)) + : nextTickPromise(), + undefined + ); + nextTick.ntp = nextTickPromise; + + return nextTick; +})(); +</pre> + +<h2 id="Специфікації">Специфікації</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Специфікація</th> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-promise.prototype.then', 'Promise.prototype.then')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Сумісність_з_веб-переглядачами">Сумісність з веб-переглядачами</h2> + +<p class="hidden">To contribute to this compatibility data, please write a pull request against this repository: <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a>.</p> + +<p>{{Compat("javascript.builtins.Promise.then")}}</p> + +<h2 id="Див._також">Див. також</h2> + +<ul> + <li>{{jsxref("Promise")}}</li> + <li>{{jsxref("Promise.prototype.catch()")}}</li> +</ul> |