diff options
author | Ryan Johnson <rjohnson@mozilla.com> | 2021-04-29 16:16:42 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-29 16:16:42 -0700 |
commit | 95aca4b4d8fa62815d4bd412fff1a364f842814a (patch) | |
tree | 5e57661720fe9058d5c7db637e764800b50f9060 /files/uk/web/javascript/guide/using_promises | |
parent | ee3b1c87e3c8e72ca130943eed260ad642246581 (diff) | |
download | translated-content-95aca4b4d8fa62815d4bd412fff1a364f842814a.tar.gz translated-content-95aca4b4d8fa62815d4bd412fff1a364f842814a.tar.bz2 translated-content-95aca4b4d8fa62815d4bd412fff1a364f842814a.zip |
remove retired locales (#699)
Diffstat (limited to 'files/uk/web/javascript/guide/using_promises')
-rw-r--r-- | files/uk/web/javascript/guide/using_promises/index.html | 363 |
1 files changed, 0 insertions, 363 deletions
diff --git a/files/uk/web/javascript/guide/using_promises/index.html b/files/uk/web/javascript/guide/using_promises/index.html deleted file mode 100644 index d3b986e51a..0000000000 --- a/files/uk/web/javascript/guide/using_promises/index.html +++ /dev/null @@ -1,363 +0,0 @@ ---- -title: Використання промісів -slug: Web/JavaScript/Guide/Using_promises -tags: - - JavaScript - - Promise - - Посібник - - Проміс - - асинхронний -translation_of: Web/JavaScript/Guide/Using_promises ---- -<div>{{jsSidebar("JavaScript Guide")}}</div> - -<div>{{PreviousNext("Web/JavaScript/Guide/Dokladno_pro_Objectnu_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}</div> - -<p>{{jsxref("Promise")}} (з англ. - "обіцянка", далі - "проміс") - це об'єкт, що відображає кінцеве завершення або невдачу асинхронної операції. Оскільки більшість людей є споживачами раніше створенних промісів, цей посібник спочатку пояснить споживання повернених промісів, а далі пояснить, як їх створювати.</p> - -<p>Проміс, по суті, є поверненим об'єктом, до якого ви прикріплюєте функції зворотного виклику, замість того, щоб передавати їх у функцію.</p> - -<p>Уявіть собі функцію <code>createAudioFileAsync()</code>, яка асинхронно генерує звуковий файл, маючи конфігураційний запис та дві функції зворотного виклику, одна викликається, якщо аудіофайл був успішно створений, а інша викликається, якщо виникає помилка.</p> - -<p>Ось код, який використовує <code>createAudioFileAsync()</code>:</p> - -<pre class="brush: js line-numbers language-js notranslate">function successCallback(result) { - console.log("Аудіофайл створений за адресою: " + result); -} - -function failureCallback(error) { - console.log("Під час створення аудіофайлу виникла помилка: " + error); -} - -createAudioFileAsync(audioSettings, successCallback, failureCallback); -</pre> - -<p>Замість цього, сучасні функції повертають проміс, до якого ви можете приєднати функції зворотного виклику:</p> - -<p>Якщо переписати функцію <code>createAudioFileAsync()</code>, щоб вона повертала проміс, її використання буде ось таким простим:</p> - -<pre class="brush: js notranslate">createAudioFileAsync(audioSettings).then(successCallback, failureCallback);</pre> - -<p>Це скорочений запис для:</p> - -<pre class="brush: js notranslate">const promise = createAudioFileAsync(audioSettings); -promise.then(successCallback, failureCallback);</pre> - -<p>Ми називаємо це <em>асинхронним викликом функції</em>. Ця конвенція має декілька переваг. Ми дослідимо кожну з них.</p> - -<h2 id="Гарантії">Гарантії</h2> - -<p>На відміну від старомодних колбеків, проміс постачається з певними гарантіями:</p> - -<ul> - <li>Функції зворотного виклику ніколи не будуть викликані до <a href="/uk/docs/Web/JavaScript/EventLoop">завершення поточного виконання</a> циклу подій JavaScript.</li> - <li>Функції зворотного виклику, додані за допомогою <code><a href="/uk/docs/Web/JavaScript/Reference/Global_Objects/Promise/then">then()</a></code>, навіть <em>після</em> успіху або невдачі асинхронної операції, будуть викликані, як наведено вище.</li> - <li>Можна додати більше одного зворотного виклику, викликавши метод <code><a href="/uk/docs/Web/JavaScript/Reference/Global_Objects/Promise/then">then()</a></code> декілька разів. Кожен зворотний виклик виконується один за одним, у тому порядку, в якому вони були додані.</li> -</ul> - -<p>Однією з величезних переваг промісів є <strong>ланцюгування</strong>.</p> - -<h2 id="Ланцюгування">Ланцюгування</h2> - -<p>Типовою потребою є виконання двох або більше асинхронних операцій одна за одною, коли кожна наступна операція починається, коли попередня успішно завершується, з результатом з попереднього кроку. Ми досягаємо цього, створюючи <strong>ланцюжок промісів</strong>.</p> - -<p>Ось вам магія: функція <code>then()</code> повертає <strong>новий проміс</strong>, що відрізняється від оригіналу:</p> - -<pre class="brush: js notranslate">const promise = doSomething(); -const promise2 = promise.then(successCallback, failureCallback); -</pre> - -<p>або</p> - -<pre class="brush: js notranslate">const promise2 = doSomething().then(successCallback, failureCallback); -</pre> - -<p>Цей другий проміс (<code>promise2</code>) представляє собою завершення не тільки <code>doSomething()</code>, але й <code>successCallback</code> або <code>failureCallback</code>, які ви передали, вони, в свою чергу, можуть бути іншими асинхронними функціями, що повертають проміс. В цьому випадку будь-які функції зворотного виклику, додані до <code>promise2</code>, стають в чергу за промісом, що повертається <code>successCallback</code> чи <code>failureCallback</code>.</p> - -<p>По суті, кожен проміс відображає завершення іншого асинхроннго кроку в ланцюжку.</p> - -<p>В старі часи виконання декількох асинхронних операцій підряд призвело б до класичної піраміди смерті з колбеків:</p> - -<pre class="brush: js notranslate">doSomething(function(result) { - doSomethingElse(result, function(newResult) { - doThirdThing(newResult, function(finalResult) { - console.log('Ось фінальний результат: ' + finalResult); - }, failureCallback); - }, failureCallback); -}, failureCallback); -</pre> - -<p>З сучасними функціями замість цього ми приєднуємо наші функції зворотного виклику до промісів, що повертаються, формуючи ланцюжок промісів.</p> - -<pre class="brush: js notranslate">doSomething().then(function(result) { - return doSomethingElse(result); -}) -.then(function(newResult) { - return doThirdThing(newResult); -}) -.then(function(finalResult) { - console.log('Ось фінальний результат: ' + finalResult); -}) -.catch(failureCallback); -</pre> - -<p>Аргументи до <code>then</code> є необов'язковими, а <code>catch(failureCallback)</code> - це скорочений запис для <code>then(null, failureCallback)</code>. Ви можете побачити це, виражене за допомогою <a href="/uk/docs/Web/JavaScript/Reference/Functions/Стрілкові_функції">стрілкових функцій</a>:</p> - -<pre class="brush: js notranslate">doSomething() -.then(result => doSomethingElse(result)) -.then(newResult => doThirdThing(newResult)) -.then(finalResult => { - console.log(`Ось фінальний результат: ${finalResult}`); -}) -.catch(failureCallback); -</pre> - -<p><strong>Важливо</strong>: Завжди повертайте результати, інакше функції зворотного виклику не перехоплять результат попереднього проміса (у стрілкових функціях <code>() => x</code> є скороченим записом для <code>() => { return x; }</code>).</p> - -<h3 id="Ланцюгування_після_catch">Ланцюгування після catch</h3> - -<p>Ланцюгувати <em>після </em>невдачі можливо, наприклад, <code>catch</code> є корисним у разі виконання нових операцій навіть після того, як операція у ланцюжку завершилась неуспішно. Дивіться наступний приклад:</p> - -<pre class="brush: js notranslate">new Promise((resolve, reject) => { - console.log('Початковий'); - - resolve(); -}) -.then(() => { - throw new Error('Щось пішло не так'); - - console.log('Зробити це'); -}) -.catch(() => { - console.log('Зробити те'); -}) -.then(() => { - console.log('Зробити це, що б не відбувалось раніше'); -}); - -</pre> - -<p>Це виведе наступний текст:</p> - -<pre class="notranslate">Початковий -Зробити те -Зробити це, що б не відбувалось раніше -</pre> - -<p><strong>Зауважте:</strong> Текст "Зробити це" не був виведений, тому що помилка "Щось пішло не так" спричинила відхилення.</p> - -<h2 id="Спливання_помилок">Спливання помилок</h2> - -<p>Ви, можливо, пригадуєте, що тричі бачили <code>failureCallback</code> раніше, у піраміді смерті, у порівнянні з лише одним викликом наприкінці ланцюжку промісів.</p> - -<pre class="brush: js notranslate">doSomething() -.then(result => doSomethingElse(value)) -.then(newResult => doThirdThing(newResult)) -.then(finalResult => console.log(`Ось фінальний результат: ${finalResult}`)) -.catch(failureCallback); -</pre> - -<p>Якщо виникає виняток, переглядач передивляється ланцюжок у пошуках обробників <code>catch</code> або <code>onRejected</code>. Це дуже схоже на модель того, як працює синхронний код:</p> - -<pre class="brush: js notranslate">try { - let result = syncDoSomething(); - let newResult = syncDoSomethingElse(result); - let finalResult = syncDoThirdThing(newResult); - console.log(`Ось фінальний результат: ${finalResult}`); -} catch(error) { - failureCallback(error); -} -</pre> - -<p>Ця симетрія з асинхронним кодом сягає кульмінації в синтаксичному цукрі <a href="/uk/docs/Web/JavaScript/Reference/Statements/async_function"><code>async</code>/<code>await</code></a> в ECMAScript 2017:</p> - -<pre class="brush: js notranslate">async function foo() { - try { - let result = await doSomething(); - let newResult = await doSomethingElse(result); - let finalResult = await doThirdThing(newResult); - console.log(`Ось фінальний результат: ${finalResult}`); - } catch(error) { - failureCallback(error); - } -} -</pre> - -<p>Він будується на промісах, наприклад, <code>doSomething()</code> - це та сама функція, що й раніше. Ви можете прочитати більше про синтаксис <a href="https://developers.google.com/web/fundamentals/primers/async-functions">тут</a>.</p> - -<p>Проміси виправляють фундаментальну хибу з пірамідою смерті, перехоплюючи всі помилки, навіть викинуті винятки та помилки программування. Це критично важливо для функціональної композиції асинхронних операцій.</p> - -<h2 id="Події_відхилення_промісів">Події відхилення промісів</h2> - -<p>Коли проміс відхиляється, одна з двох подій надсилається у глобальну область видимості (загалом, це або <a href="/uk/docs/Web/API/Window"><code>window</code></a>, або, при використанні у веб-виконавці, це <a href="/uk/docs/Web/API/Worker"><code>Worker</code></a> або інший інтерфейс на базі виконавців). Ці дві події наступні:</p> - -<dl> - <dt><a href="/uk/docs/Web/API/Window/rejectionhandled_event" title="Подія rejectionhandled надсилається у глобальну область видимості скрипта (зазвичай, window, але також і Worker), коли об'єкт JavaScript Promise відхиляється, але після того, як відхилення було оброблене."><code>rejectionhandled</code></a></dt> - <dd>Надсилається, коли проміс відхиляється, після того, як відхилення було оброблене функцією виконавця <code>reject</code>.</dd> - <dt><a href="/uk/docs/Web/API/Window/unhandledrejection_event" title="Подія unhandledrejection надсилається у глобальну область видимості скрипта, коли об'єкт JavaScript Promise, який не має обробника відхилення, відхиляється; зазвичай, це window, але також може бути Worker."><code>unhandledrejection</code></a></dt> - <dd>Надсилається, коли проміс відхиляється, але немає доступного обробника відхилення.</dd> -</dl> - -<p>У обох випадках подія (типу <a href="/uk/docs/Web/API/PromiseRejectionEvent" title="Інтерфейс PromiseRejectionEvent відображає події, які надсилаються у глобальний контекст скрипта, коли об'єкти JavaScript Promise відхиляються."><code>PromiseRejectionEvent</code></a>) має в якості полів властивість <a href="/uk/docs/Web/API/PromiseRejectionEvent/promise"><code>promise</code></a>, яка вказує відхилений проміс, та властивість <a href="/uk/docs/Web/API/PromiseRejectionEvent/reason"><code>reason</code></a>, яка передає надану причину відхилення проміса.</p> - -<p>Це робить можливою резервну обробку помилок для промісів, а також допомагає відлагоджувати проблеми в управлінні промісами. Ці обробники є глобальними за контекстом, тому усі помилки потраплятимуть в однакові обробники подій, незалежно від джерела.</p> - -<p>Один випадок особливої корисності: при написанні коду для {{Glossary("Node.js")}}, зазвичай, модулі, які ви включаєте у свій проект, можуть мати необроблені відхилені проміси. Вони виводяться у консоль середовищем виконання Node. Ви можете перехопити їх для аналізу та обробити у своєму коді — або просто уникнути захаращення ними виводу даних — додавши обробник події <a href="/uk/docs/Web/API/Window/unhandledrejection_event"><code>unhandledrejection</code></a>, ось так:</p> - -<pre class="brush: js notranslate">window.addEventListener("unhandledrejection", event => { - /* Ви можете почати тут, додавши код, щоб дослідити - вказаний проміс через event.promise та причину у - event.reason */ - - event.preventDefault(); -}, false);</pre> - -<p>Викликавши метод події <a href="/uk/docs/Web/API/Event/preventDefault" title="Метод інтерфейсу Event preventDefault() каже програмному агенту, що, якщо подія не була явно оброблена, її дія за замовчуванням не має виконуватись."><code>preventDefault()</code></a>, ви кажете середовищу виконання JavaScript не виконувати дію за замовчуванням, коли відхилений проміс лишається необробленим. Ця дія зазвичай містить виведення помилки у консоль, а це якраз випадок для Node.</p> - -<p>В ідеалі, звісно, ви маєте досліджувати відхилені проміси, щоб бути певними, що жоден з них не є насправді помилкою коду, перед тим, як відкидати ці події.</p> - -<h2 id="Створення_промісу_на_основі_старого_API_зі_зворотним_викликом">Створення промісу на основі старого API зі зворотним викликом</h2> - -<p>{{jsxref("Promise","Проміс")}} може бути створенний з нуля за допогою свого конструктора. Це необхідно лише для обгортки старих API.</p> - -<p>В ідеальному світі всі асинхронні функції повертали б проміси. На жаль, деякі API досі очікують старомодну передачу функцій зворотного виклику для успіху та/або невдачі. Найбільш очевидним прикладом є функція {{domxref("WindowTimers.setTimeout", "setTimeout()")}} :</p> - -<pre class="brush: js notranslate">setTimeout(() => saySomething("Пройшло 10 секунд"), 10000); -</pre> - -<p>Змішування старомодних зворотних викликів та промісів є проблематичним. Якщо <code>saySomething</code> завершиться невдачею або міститиме помилку программування, ніщо її не перехопить.</p> - -<p>На щастя, ми можемо обгорнути <code>saySomething</code> у проміс. Найкращою практикою вважається обгортати проблематичні функції на якомога нижчому рівні і вже ніколи не звертатись до них прямо.</p> - -<pre class="brush: js notranslate">const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); - -wait(10000).then(() => saySomething("10 секунд")).catch(failureCallback); -</pre> - -<p>По суті, конструктор промісу приймає функцію виконання, яка дозволяє вирішити або відхилити проміс вручну. Оскільки <code>setTimeout</code>, насправді, ніколи не завершується невдало, ми пропускаємо функцію відхилення в цьому випадку.</p> - -<h2 id="Композиція">Композиція</h2> - -<p>Методи {{jsxref("Promise.resolve()")}} та {{jsxref("Promise.відхилено", "Promise.reject()")}} є скороченими записами для створення вручну вже вирішених або відхилених промісів відповідно. Інколи це може бути корисно.</p> - -<p>Методи {{jsxref("Promise.all()")}} та {{jsxref("Promise.race()")}} є двома інструментами композиції для паралельного виконання асинхронних операції.</p> - -<p>Ми можемо почати операції паралельно та чекати, доки вони усі не завершаться ось так:</p> - -<pre class="brush: js notranslate">Promise.all([func1(), func2(), func3()]) -.then(([result1, result2, result3]) => { /* використати result1, result2 та result3 */ });</pre> - -<p>Послідовна композиція можлива з використанням певного розумного JavaScript:</p> - -<pre class="brush: js notranslate">[func1, func2, func3].reduce((p, f) => p.then(f), Promise.resolve()) -.then(result3 => { /* використати result3 */ });</pre> - -<p>По суті, ми зменшуємо масив асинхронних функцій до ланцюжка промісів, еквівалентного: <code>Promise.resolve().then(func1).then(func2).then(func3);</code></p> - -<p>Це можна перетворити на композиційну функцію багаторазового використання, що є типовим у функціональному програмуванні:</p> - -<pre class="brush: js notranslate">const applyAsync = (acc,val) => acc.then(val); -const composeAsync = (...funcs) => x => funcs.reduce(applyAsync, Promise.resolve(x));</pre> - -<p>Функція <code>composeAsync()</code> прийме будь-яку кількість функцій в якості аргументів і поверне нову функцію, яка приймає початкове значення, що має пройти крізь конвеєр композиції:</p> - -<pre class="brush: js notranslate">const transformData = composeAsync(func1, func2, func3); -const result3 = transformData(data); -</pre> - -<p>В ECMAScript 2017 послідовну композицію можна виконати простіше, за допомогою async/await:</p> - -<pre class="brush: js notranslate">let result; -for (const f of [func1, func2, func3]) { - result = await f(result); -} -/* використати останній результат (тобто, result3) */</pre> - -<h2 id="Хронометраж">Хронометраж</h2> - -<p>Щоб уникнути сюрпризів, функції, передані до <code>then()</code>, ніколи не викликатимуться синхронно, навіть для вже вирішеного проміса:</p> - -<pre class="brush: js notranslate">Promise.resolve().then(() => console.log(2)); -console.log(1); // 1, 2 -</pre> - -<p>Замість негайного виконання, передані функції ставляться у чергу мікрозадач. Це означає, що вони виконуються пізніше, коли черга стає порожньою в кінці поточного виконання циклу подій JavaScript, тобто, досить скоро:</p> - -<pre class="brush: js notranslate">const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); - -wait().then(() => console.log(4)); -Promise.resolve().then(() => console.log(2)).then(() => console.log(3)); -console.log(1); // 1, 2, 3, 4 -</pre> - -<h2 id="Вкладеність">Вкладеність</h2> - -<p>Прості ланцюжки промісів найкраще тримати рівними, без вкладень, оскільки вкладення можуть бути результатом недбалої композиції. Дивіться <a href="#Типові_помилки">типові помилки</a>.</p> - -<p>Вкладеність є контролюючою структурою для обмеження області видимості блоків <code>catch</code>. Зокрема, вкладений <code>catch</code> перехоплює лише помилки своєї області видимості та нижче, але не ті помилки, що знаходяться вище у ланцюжку поза вкладеною областю видимості. При правильному використанні це надає більшу точність у виявленні помилок:</p> - -<pre class="brush: js notranslate">doSomethingCritical() -.then(result => doSomethingOptional(result) - .then(optionalResult => doSomethingExtraNice(optionalResult)) - .catch(e => {})) // Ігнорувати, якщо не працює щось другорядне; продовжити. -.then(() => moreCriticalStuff()) -.catch(e => console.error("Критична помилка: " + e.message));</pre> - -<p>Зауважте, що необов'язкові кроки тут вкладені, не для відступів, але для передбачливого розташування зовнішніх дужок <code>(</code> та <code>)</code> навколо.</p> - -<p>Внутрішній нейтралізуючий блок <code>catch</code> перехоплює помилки тільки від <code>doSomethingOptional()</code> та <code>doSomethingExtraNice()</code>, після чого виконання коду продовжується у <code>moreCriticalStuff()</code>. Що важливо, якщо функція <code>doSomethingCritical()</code> завершується невдало, її помилка перехоплюється тільки кінцевим (зовнішнім) блоком <code>catch</code>.</p> - -<h2 id="Типові_помилки">Типові помилки</h2> - -<p>Ось деякі типові помилки, яких варто остерігатися при складанні ланцюжків промісів. Декілька з цих помилок проявляються у наступному прикладі:</p> - -<pre class="brush: js example-bad notranslate">// Поганий приклад! Помічено 3 помилки! - -doSomething().then(function(result) { - doSomethingElse(result) // Забули повернути проміс з внутрішнього ланцюжка + непотрібне вкладення - .then(newResult => doThirdThing(newResult)); -}).then(() => doFourthThing()); -// Забули завершити ланцюжок блоком catch! -</pre></pre> - -<p>Перша помилка - не завершувати ланцюжки як слід. Це відбувається, коли ми створюємо новий проміс, але забуваємо його повернути. Як наслідок, ланцюг переривається, чи, скоріше, ми отримуємо два конкуруючі ланцюжки. Це означає, що <code>doFourthThing()</code> не чекатиме на завершення <code>doSomethingElse()</code> чи <code>doThirdThing()</code> і запуститься паралельно з ними, скоріше за все, ненавмисно. В окремих ланцюжках також окремо обробляються помилки, що призводить до неперехоплених помилок.</p> - -<p>Друга помилка - непотрібна вкладеність, що уможливлює першу помилку. Вкладеність також обмежує область видимості внутрішніх обробників помилок, а це — якщо зроблене ненавмисно — може призвести до неперехоплених помилок. Варіантом цього є <a href="https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it">антишаблон конструювання промісів</a>, який поєднує вкладення з надлишковим використанням конструктора промісів для загортання коду, який вже використовує проміси.</p> - -<p>Третя помилка - забувати завершувати ланцюжки блоком <code>catch</code>. Незавершені ланцюжки промісів призводять до неперехоплених відхилень промісів у більшості переглядачів.</p> - -<p>Гарний практичний підхід - завжди або повертати, або завершувати ланцюжки промісів, і, як тільки ви отримуєте новий проміс, повертати його негайно, щоб вирівняти ланцюжок:</p> - -<pre class="brush: js example-good notranslate">doSomething() -.then(function(result) { - return doSomethingElse(result); -}) -.then(newResult => doThirdThing(newResult)) -.then(() => doFourthThing()) -.catch(error => console.error(error));</pre> - -<p>Зауважте, що <code>() => x</code> є скороченням для <code>() => { return x; }</code>.</p> - -<p>Тепер ми маємо єдиний, детермінований ланцюжок з правильною обробкою помилок.</p> - -<p>Використання <a href="/uk/docs/Web/JavaScript/Reference/Statements/async_function"><code>async</code>/<code>await</code></a> вирішує більшість, якщо не всі ці проблеми — натомість, найпоширенішою помилкою при використанні цього синтаксису є забуте ключове слово <a href="/uk/docs/Web/JavaScript/Reference/Statements/async_function"><code>await</code></a>.</p> - -<h2 id="Коли_зустрічаються_задачі_та_проміси">Коли зустрічаються задачі та проміси</h2> - -<p>Якщо ви стикаєтеся з ситуаціями, коли у вас є проміси та задачі (такі, як події або зворотні виклики), які запускаються у непередбачуваному порядку, можливо, вам буде корисно скористатись мікрозадачами, щоб перевірити статус або збалансувати проміси, коли створення промісів залежить від певних умов.</p> - -<p>Якщо ви вважаєте, що мікрозадачі могли б вирішити цю проблему, дивіться <a href="/uk/docs/Web/API/HTML_DOM_API/Microtask_guide">посібник з мікрозадач</a>, щоб дізнатись, як використовувати метод <code><a href="/uk/docs/Web/API/WindowOrWorkerGlobalScope/queueMicrotask" title="The queueMicrotask() method, which is exposed on the Window or Worker interface, queues a microtask to be executed at a safe time prior to control returning to the browser's event loop.">queueMicrotask()</a></code>, щоб поставити функцію у чергу як мікрозадачу.</p> - -<h2 id="Дивіться_також">Дивіться також</h2> - -<ul> - <li>{{jsxref("Promise.then()")}}</li> - <li><a href="/uk/docs/Web/JavaScript/Reference/Statements/async_function"><code>async</code>/<code>await</code></a> </li> - <li><a href="http://promisesaplus.com/">Promises/A+ specification</a></li> - <li><a href="https://medium.com/@ramsunvtech/promises-of-promise-part-1-53f769245a53">Venkatraman.R - JS Promise (Part 1, Basics)</a></li> - <li><a href="https://medium.com/@ramsunvtech/js-promise-part-2-q-js-when-js-and-rsvp-js-af596232525c#.dzlqh6ski">Venkatraman.R - JS Promise (Part 2 - Using Q.js, When.js and RSVP.js)</a></li> - <li><a href="https://tech.io/playgrounds/11107/tools-for-promises-unittesting/introduction">Venkatraman.R - Tools for Promises Unit Testing</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> -</ul> - -<p>{{PreviousNext("Web/JavaScript/Guide/Dokladno_pro_Objectnu_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}</p> |