1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
|
---
title: Promises benutzen
slug: Web/JavaScript/Guide/Using_promises
translation_of: Web/JavaScript/Guide/Using_promises
---
<div>{{jsSidebar("JavaScript Guide")}}{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}</div>
<p class="summary">Ein {{jsxref("Promise")}} ist ein Objekt, das die finale Beendigung einer asynchronen Operation repräsentiert. Je nachdem, ob die Operation erfolgreich oder fehlerhaft beendet wurde, wird das Promise entsprechend gekennzeichnet.</p>
<p class="summary">Da in den meisten Fällen bereits existierende Promises benutzt werden, wird diese Anleitung zuerst die Benutzung von zurückgegebenen Promises erklären, und dann darauf eingehen, wie diese erzeugt werden.</p>
<p class="summary">Grob gesagt ist ein Promise ein zurückgegebenes Objekt, an welches Callback-Funktionen angehängt werden können, anstatt dass diese einer Funktion übergeben werden.</p>
<p class="summary">Betrachten wir z.B. folgende Funktion <code>createAudioFileAsync()</code>, welche asynchron eine Audio-Datei generiert; an diese werden Audio-Einstellungen sowie zwei Callback-Funktionen übergeben - eine für das erfolgreiche Erzeugen der Audio-Datei, und die andere für auftretende Fehler.</p>
<p class="summary">Ein beispielhafter Code, den <code>createAudioFileAsync()</code> nutzen würde, sieht in etwa so aus:</p>
<pre class="summary notranslate">function successCallback(result) {
console.log("Audio-Datei bereit unter URL: " + result);
}
function failureCallback(error) {
console.error("Fehlerhafte Generierung der Audio-Datei: " + error);
}
createAudioFileAsync(audioSettings, successCallback, failureCallback);
</pre>
<p>In modernen Funktionen, welche Promises zurückgeben, kann man die Callbacks stattdessen direkt anhängen:</p>
<p>Würde <code>createAudioFileAsync()</code> so umgeschrieben, dass es als Rückgabewert ein Promise hätte, wäre die Nutzung davon einfach so:</p>
<pre class="notranslate">createAudioFileAsync(audiosettings).then(successCallback, failureCallback);</pre>
<p>Das ist die Kurzform von:</p>
<pre class="notranslate">const promise = createAudioFileAsync(audioSettings);
promise.then(successCallback, failureCallback);
</pre>
<p>Dies nennt man einen <em>asynchronen Funktionsaufruf</em>. Diese Vorgehensweise hat mehrere Vorteile, von denen in diesem Artikel jeder einzeln geschildert wird.</p>
<h2 id="Garantien">Garantien</h2>
<p>Anders als bei Callback-Übergabe nach dem alten Verfahren, können Promise-Objekte folgendes sicherstellen:</p>
<ul>
<li>Callback-Funktionen werden erst aufgerufen, wenn der <a href="/en-US/docs/Web/JavaScript/EventLoop#Run-to-completion">derzeitige Durchlauf des Javascript Event Loops </a>vollständig ist.</li>
<li>Callback-Funktionen, die in <code>.then()</code> angehängt werden, werden <em>nach</em> dem Ende der asynchronen Operation aufgerufen.</li>
<li>Mehrere Callback-Funktionen können durch mehrmaliges Aufrufen von <code>.then()</code> angehängt werden, um unabhängig von der Funktion selbst in der Anhänge-Reihenfolge aufgerufen zu werden.</li>
</ul>
<p>Allerdings ist der wohl kurzfristigste Nutzen von Promises das Chaining.</p>
<h2 id="Chaining">Chaining</h2>
<p>Eine häufige Aufgabenstellung ist der Aufruf von zwei oder mehr asynchronen Funktionen nacheinander in Sequenz, wobei Ergebnisse aus der vorangegangenen Funktion in die folgende Funktion übernommen werden. Dies ist realisierbar mittels einer <em>Promise chain</em>.</p>
<p>Hier steckt der Zauber drin: Die Funktion <code>.then()</code> gibt stets ein neues Promise-Objekt zurück:</p>
<pre class="brush: js notranslate">const promise = doSomething();
const promise2 = promise.then(successCallback, failureCallback);
</pre>
<p>oder auch</p>
<pre class="brush: js notranslate">const promise2 = doSomething().then(successCallback, failureCallback);
</pre>
<p>Hierbei repräsentiert <code>promise2</code> nicht nur den vollständigen Aufruf von <code>doSomething()</code>, sondern auch die Ergebnisse der beiden angehängten Funktionen <code>successCallback</code> oder <code>failureCallback</code> - diese können ebenfalls asynchrone Funktionen sein, die Promises zurückgeben. In diesem Fall werden jegliche Callback-Funktionen, die an <code>promise2</code> angehängt würden, jeweils auch eingereiht in den jeweiligen Promise-Rückgabewerten von <code>successCallback</code> oder <code>failureCallback</code>.</p>
<p>Grundsätzlich repräsentiert jedes Promise-Objekt die Vervollständigung eines asynchronen Schritts in der Kette.</p>
<p>Nach dem alten Verfahren führte das Aneinanderreihen von mehreren asynchronen Operationen zur klassischen <em>Callback pyramid of doom</em>:</p>
<pre class="brush: js notranslate">doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult);
}, failureCallback);
}, failureCallback);
}, failureCallback);
</pre>
<p>Mit moderenen Funktionen können diese Callback-Funktionen stattdessen an die zurückgegebenen Promise-Objekte angehängt werden, womit die <em>Promise chain</em> geformt wird:</p>
<pre class="brush: js notranslate">doSomething().then(function(result) {
return doSomethingElse(result);
})
.then(function(newResult) {
return doThirdThing(newResult);
})
.then(function(finalResult) {
console.log('Got the final result: ' + finalResult);
})
.catch(failureCallback);
</pre>
<p>Die Argumente für <code>.then()</code> sind optional, und <code>.catch(failureCallback)</code> ist die Kurzschreibform von <code>.then(null, failureCallback)</code>. Dies kann stattdessen auch mit <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">Pfeil-Funktionen</a> ausgedrückt werden:</p>
<pre class="brush: js notranslate">doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => {
console.log(`Got the final result: ${finalResult}`);
})
.catch(failureCallback);
</pre>
<p><strong>Wichtig</strong>: Immer Rückgabewerte angeben; sonst können die Callback das Ergebnis eines vorherigen Promise nicht abfangen.</p>
<h3 id="Chaining_nach_einem_.catch">Chaining nach einem <code>.catch()</code></h3>
<p>Es ist auch möglich, nach einem Fehler, sprich <code>.catch()</code>, weiter zu verkettern. Dies ist nützlich um neue Operationen auszuführen, auch nachdem es einen Fehler in der Kette gab.</p>
<pre class="brush: js notranslate">new Promise((resolve, reject) => {
console.log('Initial');
resolve();
})
.then(() => {
throw new Error('Something failed');
console.log('Do this');
})
.catch(() => {
console.log('Do that');
})
.then(() => {
console.log('Do this, no matter what happened before');
});
</pre>
<p>Das obige Beispiel hat die nachfolgenden Ausgaben:</p>
<pre class="notranslate">Initial
Do that
Do this, no matter what happened before
</pre>
<p>Zu beachten ist hier, dass der Text "Do this" nicht ausgegeben wird, weil der Fehler "Something failed" einen Abbruch ausgelöst hat.</p>
<h2 id="Fehlerübertragung">Fehlerübertragung</h2>
<p>Schaut man sich weiter oben die <em>Callback pyramid of doom</em> an, wird sichtbar, dass <code>failureCallback</code> dort mehrmals angegeben werden muss, anders als nur einmal beim Beispiel unten:</p>
<pre class="brush: js notranslate">doSomething()
.then(result => doSomethingElse(result))
.then(newResult => doThirdThing(newResult))
.then(finalResult => console.log(`Got the final result: ${finalResult}`))
.catch(failureCallback);
</pre>
<p>Grundsätzlich hält eine Promise chain bei einer Exception an und erlaubt nur noch Zugriffe von <code>.catch()</code>-Handlern. Dies ist modelliert nach der Funktionsweise von synchronem Code:</p>
<pre class="brush: js notranslate">try {
const result = syncDoSomething();
const newResult = syncDoSomethingElse(result);
const finalResult = syncDoThirdThing(newResult);
console.log(`Got the final result: ${finalResult}`);
} catch(error) {
failureCallback(error);
}
</pre>
<p>Diese Symmetrie mit synchronem Code erreichte ihren Höhepunkt in der <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/async_function">async/await</a></code>-Komfortschreibweise in ECMAScript 2017:</p>
<pre class="brush: js notranslate">async function foo() {
try {
const result = await doSomething();
const newResult = await doSomethingElse(result);
const finalResult = await doThirdThing(newResult);
console.log(`Got the final result: ${finalResult}`);
} catch(error) {
failureCallback(error);
}
}
</pre>
<p>Diese Schreibweise baut auf Promises auf; so ist <code>doSomething()</code> die selbe Funktion wie vorher. <a href="https://developers.google.com/web/fundamentals/getting-started/primers/async-functions">Hier</a> kann man mehr über diese Syntax erfahren.</p>
<p>Promise-Objekte lösen mit der <em>Callback pyramid of doom </em>ein fundamentales Designproblem, indem sie alle Fehler, auch geworfene Exceptions und Programmierfehler, abfangen. Diese Eigenschaft ist essentiell für die funktionale Komposition von asynchronen Operationen.</p>
<h2 id="Promise_rejection-Events">Promise rejection-Events</h2>
<p>Immer, wenn ein Promise abgelehnt ("rejected") wird, wird eines von zwei Events zum globalen Scope (grundsätzlich entweder <code><a href="/de/docs/Web/API/Window">window</a></code>, oder, falls in einem Web-Worker gearbeitet wird, der <code><a href="/de/docs/Web/API/Worker">Worker</a></code> selbst oder ein anderes, <code>Worker</code>-basiertes Interface) geschickt. Diese beiden Events sind:</p>
<dl>
<dt><code><a href="/en-US/docs/Web/API/Window/rejectionhandled_event">rejectionHandled</a></code></dt>
<dd>Wird bei der Ablehnung eines Promise gesendet, nachdem die Ablehnung von der reject-Funktion des Ausführenden verarbeitet wurde.</dd>
<dt><code><a href="/en-US/docs/Web/API/Window/unhandledrejection_event">unhandledRejection</a></code></dt>
<dd>Wird bei der Ablehnung eines Promise gesendet, wenn es keinen Rejection-Handler gibt.</dd>
</dl>
<p>In beiden Fällen hat das Event (vom Typ <code><a href="/en-US/docs/Web/API/PromiseRejectionEvent">PromiseRejectionEvent</a></code>) als Member das Attribut <code><a href="/en-US/docs/Web/API/PromiseRejectionEvent/promise">promise</a></code> welches auf das abgelehnte Promise zeigt, sowie ein Attribut <code><a href="/en-US/docs/Web/API/PromiseRejectionEvent/reason">reason</a></code> welches eine Begründung für die Ablehnung des Promise enthält.</p>
<p>Diese Events bilden ein Fallback für die Fehlerbehandlung bei Promises sowie eine Hilfestellung beim Debugging des eigenen Promise-Managements. Da die Händler im Kontext global sind, werden alle Fehler unabhängig von der Quelle zu ihnen geschickt.</p>
<p>Ein Fall der besonderen Nützlichkeit: Wenn man Code in <a href="/de/docs/Glossary/Node.js">Node.js</a> schreibt, kann es oft passieren, dass im Projekt hinzugefügte Module unverarbeitete abgelehnte Promises haben. Diese werden von der Node-Laufzeitumgebung in die Konsole geloggt. Zu Analysezwecken, zur Verarbeitung durch den eigenen Code, oder auch einfach zur Verhinderung von übermäßigem Output, kann man diese abgelehnten Promises einfangen, indem man für das <a href="/en-US/docs/Web/API/Window/unhandledrejection_event"><code>unhandledrejection</code> event</a> einen Handler hinzufügen:</p>
<pre class="brush: js notranslate">window.addEventListener('unhandledrejection', event => {
/* Hier lässt sich Code einfügen, um die Attribute des Events
zu untersuchen */
event.preventDefault();
}, false);</pre>
<p>Indem die <code><a href="/en-US/docs/Web/API/Event/preventDefault">preventDefault()</a></code>-Methode des Events aufgerufen wird, wird die standardmäßige Operation bei unverarbeiteten abgelehnten Promises verhindert. Üblicherweise beinhaltet dies das Loggen des Fehlers in der Konsole; im Fall von Node ist das tatsächlich der Fall.</p>
<p>Idealerweise sollte man abgelehnte Promises immer untersuchen, um sicher zu gehen, dass es sich nicht um Code-Fehler handelt.</p>
<h2 id="Ein_Promise-Objekt_in_einer_alten_Callback-API_erzeugen">Ein Promise-Objekt in einer alten Callback-API erzeugen</h2>
<p>Ein einfaches {{jsxref("Promise")}} kann durch dessen Konstruktor-Methode erzeugt werden. Diese Art und Weise sollte nur genutzt werden, um alte APIs damit zu umschließen.</p>
<p>Idealerweise würden alle asynchronen Funktionen bereits Promises zurückgeben. In der Realität erwarten einige APIs immer Callback-Funktionen für Erfolg und Fehlerfall, die nach dem alten Prinzip übergeben werden müssen. Ein eindeutiges Beispiel hierfür ist die Funktion {{domxref("WindowTimers.setTimeout", "setTimeout()")}}:</p>
<pre class="brush: js notranslate">setTimeout(() => saySomething("10 seconds passed"), 10000);
</pre>
<p>Callback-Funktionen nach dem alten Verfahren und Promises zu vermischen, bringt Probleme mit sich. Wenn <code>saySomething()</code> fehlschlägt oder Programmierfehler enthält, wird dies durch nichts abgefangen.</p>
<p>Glücklicherweise kann man solche Fälle mit einem Promise umschließen. Ein Best Practice besteht darin, problematische Funktionen auf der niedrigstmöglichen Ebene zu umschließen, und sie nie wieder direkt aufzurufen:</p>
<pre class="brush: js notranslate">const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
wait(10000).then(() => saySomething("10 seconds")).catch(failureCallback);
</pre>
<p>Der Promise-Konstruktor empfängt grundsätzlich eine Ausführenden-Funktion, die es möglich macht, ein Promise manuell aufzulösen oder abzulehnen. Da <code>setTimeout()</code> nicht wirklich fehlschlägt, wurde im oberen Beispiel die Ablehnung ausgelassen.</p>
<h2 id="Komposition">Komposition</h2>
<p>{{jsxref("Promise.resolve()")}} und {{jsxref("Promise.reject()")}} sind Abkürzungen für das manuelle Erzeugen von jeweils bereits aufgelösten oder abgelehnten Promises. In bestimmten Fällen kann dies nützlich sein.</p>
<p>{{jsxref("Promise.all()")}} und {{jsxref("Promise.race()")}} sind zwei Kompositionswerkzeuge für das parallele Durchführen von asynchronen Operationen.</p>
<p>Sequenzielle Komposition ist möglich durch cleveres Javascript:</p>
<pre class="notranslate">[func1, func2].reduce((p, f) => p.then(f), Promise.resolve());</pre>
<p>Im oberen Beispiel wird ein Array von asynchronen Funktionen auf eine Promise chain reduziert. Somit ist es das gleiche, wie <code>Promise.resolve().then(func1).then(func2);</code>.</p>
<p>Auch ist es möglich, dies mit einer wiederverwendbaren Kompositionsfunktion umzusetzen, die häufig in der funktionalen Programmierung vorkommt:</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>Die Funktion <code>composeAsync()</code> akzeptiert eine dynamische Anzahl von Funktionen als Parameter, und hat als Rückgabewert eine Funktion, die einen Initialwert akzeptiert, welcher durch die Kompositions-Pipeline durchgereicht wird. Der Nutzen besteht darin, dass einige oder alle übergebenen Funktionen entweder synchron oder asynchron sein können, und garantiert wird, dass sie in der richtigen Reihenfolge ausgeführt werden.</p>
<pre class="brush: js notranslate">const transformData = composeAsync(func1, asyncFunc1, asyncFunc2, func2);
transformData(data);
</pre>
<p>In ECMAScript 2017 kann sequenzielle Komposition mittels <code>async/await</code> noch einfacher durchgeführt werden:</p>
<pre class="brush: js notranslate">for (const f of [func1, func2]) {
await f();
}
</pre>
<h2 id="Timing">Timing</h2>
<p>Um Überraschungen vorzubeugen, werden Funktionen die an <code>.then()</code> übergeben werden niemals synchron aufgerufen, auch wenn das Promise bereits aufgelöst wurde:</p>
<pre class="brush: js notranslate">Promise.resolve().then(() => console.log(2));
console.log(1); // 1, 2
</pre>
<p>Anstatt sofort ausgeführt zu werden, wird die übergebene Funktion in eine Microtask-Warteschlange eingereiht; das bedeutet, sie wird erst ausgeführt, wenn die Warteschlange am ende des aktuellen Durchlaufs des Javascript event loops geleert wird, sprich zeitnah:</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="Nesting">Nesting</h2>
<p>Einfache Promise chains sollten möglichst flach und ohne Nesting implementiert werden, da Nesting auch das Ergebnis von undurchdachter Komposition sein kann. Siehe auch bei typischen Fehlern.</p>
<p>Als Nesting wird eine Kontrollstruktur bezeichnet, um den Scope von catch-Statements zu begrenzen. Ein nested catch fängt nur Fehler in seinem Scope und niedriger ab, nicht außerhalb. Korrekt genutzt führt dies zu höherer Präzision in der Fehlerbehandlung:</p>
<pre class="brush: js notranslate">doSomethingCritical()
.then(result => doSomethingOptional(result)
.then(optionalResult => doSomethingExtraNice(optionalResult))
.catch(e => {})) // Ignorieren, wenn optionale Operation fehlschlägt
.then(() => moreCriticalStuff())
.catch(e => console.error("Critical failure: " + e.message));</pre>
<h2 id="Typische_Fehler">Typische Fehler</h2>
<p>In diesem Abschnitt werden übliche Programmierfehler thematisiert, auf die man achten sollte, um Promise chains nicht zu kompromittieren. Im unteren Beispiel wurden drei der am häufigsten vorkommenden Fehler untergebracht:</p>
<pre class="brush: js example-bad notranslate">eineFunktion().then(function (ergebnis) {
eineZweiteFunktion(ergebnis) // Kein Promise-Rückgabewert für innere Chain + unnötiges Nesting
.then(neuesErgebnis => eineDritteFunktion(neuesErgebnis));
}).then(() => eineVierteFunktion());
// Keine Chain-Terminierung mit einem catch!</pre>
<p>Der erste Programmierfehler ist, dass die Promise chain nicht ordentlich geknüpft wurde. Passieren tut dies, wenn ein neues Promise erzeugt, aber nicht zurückgegeben wird. Das führt dazu, dass die Promise chain reisst, oder aber, dass zwei chains entstehen, die sich in einer Race condition befinden. Im Klartext heisst das, dass <code>eineVierteFunktion()</code> nicht darauf wartet, dass <code>eineZweiteFunktion()</code> oder <code>eineDritteFunktion()</code> abgeschlossen sind, und, wahrscheinlich unbeabsichtigt, parallel mit ihnen ausgeführt wird. Einzelne Promise chains haben zusätzlich eigene Fehlerbehandlungen, was in diesem Fall zu nicht abgefangenen Fehlern führt.</p>
<p>Der zweite Programmierfehler ist das unnötige Nesting, welches den ersten Fehler mitverursachen kann. Da Nesting auch den Scope der inneren Fehler-Handler begrenzt, kann dies zu nicht abgefangenen Fehlern führen. Eine Variante hiervon ist das <a href="https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it">Promise-Konstruktor-Antipattern</a>, welches Nesting mit der redundanten Nutzung eines Promise-Konstruktors, um Code, der bereits Promises nutzt, zu umschließen, kombiniert.</p>
<p>Der dritte Programmierfehler ist, die Terminierung der Promise chain mit einem <code>.catch()</code> wegzulassen. Unterminierte chains führen in den meisten Browsern zu nicht abgefangenen Promise-Ablehnungen.</p>
<p>Als Faustregel sei genannt, dass Promise chains immer entweder zurückgegeben oder terminiert werden sollen, und neue Promises sofort zurückgegeben werden sollten, um die Hierarchie flach zu halten:</p>
<pre class="brush: js example-good notranslate">eineFunktion()
.then(function(ergebnis) {
return eineZweiteFunktion(ergennis);
})
.then(neuesErgebnis => eineDritteFunktion(neuesErgebnis))
.then(() => eineVierteFunktion())
.catch(fehler => console.error(fehler));</pre>
<p>Zu beachten ist, dass <code>() => x</code> die Kurzschreibform für <code>() => { return x; }</code> ist.</p>
<p>Im oberen Beispiel steht jetzt eine einzelne, deterministische Promise chain mit ordentlicher Fehlerbehandlung.</p>
<p>Das Verwenden von <a href="/en-US/docs/Web/JavaScript/Reference/Statements/async_function"><code>async</code>/<code>await</code></a> adressiert die meisten, wenn nicht alle dieser Fehlerquellen; stattdessen kann dann der typische Fehler entstehen, dass man <a href="/en-US/docs/Web/JavaScript/Reference/Statements/async_function"><code>await</code></a>-Keyword vergisst.</p>
<h2 id="Wenn_Promises_auf_Tasks_treffen">Wenn Promises auf Tasks treffen</h2>
<p>In einer Situation, in der es Promises und Tasks (z.B. Events oder Callbacks) gibt, die in einer unvorhergesehenen Reihenfolge ausgeführt werden / feuern können, ist es möglich, sich einen Microtask zunutze zu machen, um den Status von Promises zu prüfen oder diese auszubalancieren, wenn diese unter bestimmten Bedingungen erzeugt werden.</p>
<p>Für weitere Informationen über Microtasks und das Einreihen einer Funktion als Microtask mittels <code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/queueMicrotask">queueMicrotask()</a></code>, kann im <a href="/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide">Microtask-Guide</a> nachlesen.</p>
<h2 id="Siehe_auch">Siehe auch</h2>
<ul>
<li>{{jsxref("Promise.then()")}}</li>
<li><code><a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/queueMicrotask">async/await</a></code></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/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}</p>
|