-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathasync-functions-async-await.html
More file actions
225 lines (198 loc) · 62.2 KB
/
async-functions-async-await.html
File metadata and controls
225 lines (198 loc) · 62.2 KB
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
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>JavsScript - Async functions (async/await)</title>
<meta name="generator" content="VuePress 1.8.2">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="description" content="Introduction, Await and operator precedence, Async functions compared to Promises, Looping with async await, Less indentation, Simultaneous async (parallel) operations">
<meta property="og:site_name" content="DevTut">
<meta property="og:title" content="JavsScript - Async functions (async/await)">
<meta property="og:description" content="Introduction, Await and operator precedence, Async functions compared to Promises, Looping with async await, Less indentation, Simultaneous async (parallel) operations">
<meta property="og:type" content="article">
<meta property="og:url" content="/javascript/async-functions-async-await.html">
<meta property="og:image" content="/logo.png">
<meta name="twitter:title" content="JavsScript - Async functions (async/await)">
<meta name="twitter:description" content="Introduction, Await and operator precedence, Async functions compared to Promises, Looping with async await, Less indentation, Simultaneous async (parallel) operations">
<meta name="twitter:url" content="/javascript/async-functions-async-await.html">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:image" content="/logo.png">
<meta name="theme-color" content="#ffffff">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="msapplication-TileImage" content="/mstile-150x150.png">
<meta name="msapplication-TileColor" content="#da532c">
<meta name="google-site-verification" content="76_rKXgwMVIjd-axJC_1zPV9OS4mEjvtgjYOWVkAdnQ">
<link rel="preload" href="/assets/css/0.styles.60619e34.css" as="style"><link rel="preload" href="/assets/js/app.1779e102.js" as="script"><link rel="preload" href="/assets/js/3.2cfa8016.js" as="script"><link rel="preload" href="/assets/js/1704.2ef114e8.js" as="script">
<link rel="stylesheet" href="/assets/css/0.styles.60619e34.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">DevTut</span></a> <div class="links"><form id="search-form" role="search" class="algolia-search-wrapper search-box"><input id="algolia-search-input" class="search-query"></form> <nav class="nav-links can-hide"> <a href="https://github.com/devtut/generate" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"> <a href="https://github.com/devtut/generate" target="_blank" rel="noopener noreferrer" class="repo-link">
GitHub
<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav> <ul class="sidebar-links"><li><section class="sidebar-group depth-0"><p class="sidebar-heading open"><span>JavaScript</span> <!----></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/javascript/" aria-current="page" class="sidebar-link">Disclaimer</a></li><li><a href="/javascript/getting-started-with-javascript.html" class="sidebar-link">Getting started with JavaScript</a></li><li><a href="/javascript/javascript-variables.html" class="sidebar-link">JavaScript Variables</a></li><li><a href="/javascript/built-in-constants.html" class="sidebar-link">Built-in Constants</a></li><li><a href="/javascript/comments.html" class="sidebar-link">Comments</a></li><li><a href="/javascript/console.html" class="sidebar-link">Console</a></li><li><a href="/javascript/datatypes-in-javascript.html" class="sidebar-link">Datatypes in Javascript</a></li><li><a href="/javascript/strings.html" class="sidebar-link">Strings</a></li><li><a href="/javascript/date.html" class="sidebar-link">Date</a></li><li><a href="/javascript/date-comparison.html" class="sidebar-link">Date Comparison</a></li><li><a href="/javascript/comparison-operations.html" class="sidebar-link">Comparison Operations</a></li><li><a href="/javascript/conditions.html" class="sidebar-link">Conditions</a></li><li><a href="/javascript/arrays.html" class="sidebar-link">Arrays</a></li><li><a href="/javascript/objects.html" class="sidebar-link">Objects</a></li><li><a href="/javascript/arithmetic-math.html" class="sidebar-link">Arithmetic (Math)</a></li><li><a href="/javascript/bitwise-operators.html" class="sidebar-link">Bitwise operators</a></li><li><a href="/javascript/constructor-functions.html" class="sidebar-link">Constructor functions</a></li><li><a href="/javascript/declarations-and-assignments.html" class="sidebar-link">Declarations and Assignments</a></li><li><a href="/javascript/loops.html" class="sidebar-link">Loops</a></li><li><a href="/javascript/functions.html" class="sidebar-link">Functions</a></li><li><a href="/javascript/functional-javascript.html" class="sidebar-link">Functional JavaScript</a></li><li><a href="/javascript/prototypes-objects.html" class="sidebar-link">Prototypes, objects</a></li><li><a href="/javascript/classes.html" class="sidebar-link">Classes</a></li><li><a href="/javascript/namespacing.html" class="sidebar-link">Namespacing</a></li><li><a href="/javascript/context-this.html" class="sidebar-link">Context (this)</a></li><li><a href="/javascript/setters-and-getters.html" class="sidebar-link">Setters and Getters</a></li><li><a href="/javascript/events.html" class="sidebar-link">Events</a></li><li><a href="/javascript/inheritance.html" class="sidebar-link">Inheritance</a></li><li><a href="/javascript/method-chaining.html" class="sidebar-link">Method Chaining</a></li><li><a href="/javascript/callbacks.html" class="sidebar-link">Callbacks</a></li><li><a href="/javascript/intervals-and-timeouts.html" class="sidebar-link">Intervals and Timeouts</a></li><li><a href="/javascript/regular-expressions.html" class="sidebar-link">Regular expressions</a></li><li><a href="/javascript/cookies.html" class="sidebar-link">Cookies</a></li><li><a href="/javascript/web-storage.html" class="sidebar-link">Web Storage</a></li><li><a href="/javascript/data-attributes.html" class="sidebar-link">Data attributes</a></li><li><a href="/javascript/json.html" class="sidebar-link">JSON</a></li><li><a href="/javascript/ajax.html" class="sidebar-link">AJAX</a></li><li><a href="/javascript/enumerations.html" class="sidebar-link">Enumerations</a></li><li><a href="/javascript/map.html" class="sidebar-link">Map</a></li><li><a href="/javascript/timestamps.html" class="sidebar-link">Timestamps</a></li><li><a href="/javascript/unary-operators.html" class="sidebar-link">Unary Operators</a></li><li><a href="/javascript/generators.html" class="sidebar-link">Generators</a></li><li><a href="/javascript/promises.html" class="sidebar-link">Promises</a></li><li><a href="/javascript/set.html" class="sidebar-link">Set</a></li><li><a href="/javascript/modals-prompts.html" class="sidebar-link">Modals - Prompts</a></li><li><a href="/javascript/execcommand-and-contenteditable.html" class="sidebar-link">execCommand and contenteditable</a></li><li><a href="/javascript/history.html" class="sidebar-link">History</a></li><li><a href="/javascript/navigator-object.html" class="sidebar-link">Navigator Object</a></li><li><a href="/javascript/bom-browser-object-model.html" class="sidebar-link">BOM (Browser Object Model)</a></li><li><a href="/javascript/the-event-loop.html" class="sidebar-link">The Event Loop</a></li><li><a href="/javascript/strict-mode.html" class="sidebar-link">Strict mode</a></li><li><a href="/javascript/custom-elements.html" class="sidebar-link">Custom Elements</a></li><li><a href="/javascript/data-manipulation.html" class="sidebar-link">Data Manipulation</a></li><li><a href="/javascript/binary-data.html" class="sidebar-link">Binary Data</a></li><li><a href="/javascript/template-literals.html" class="sidebar-link">Template Literals</a></li><li><a href="/javascript/fetch.html" class="sidebar-link">Fetch</a></li><li><a href="/javascript/scope.html" class="sidebar-link">Scope</a></li><li><a href="/javascript/modules.html" class="sidebar-link">Modules</a></li><li><a href="/javascript/screen.html" class="sidebar-link">Screen</a></li><li><a href="/javascript/variable-coercion-conversion.html" class="sidebar-link">Variable coercion/conversion</a></li><li><a href="/javascript/destructuring-assignment.html" class="sidebar-link">Destructuring assignment</a></li><li><a href="/javascript/websockets.html" class="sidebar-link">WebSockets</a></li><li><a href="/javascript/arrow-functions.html" class="sidebar-link">Arrow Functions</a></li><li><a href="/javascript/workers.html" class="sidebar-link">Workers</a></li><li><a href="/javascript/requestanimationframe.html" class="sidebar-link">requestAnimationFrame</a></li><li><a href="/javascript/creational-design-patterns.html" class="sidebar-link">Creational Design Patterns</a></li><li><a href="/javascript/detecting-browser.html" class="sidebar-link">Detecting browser</a></li><li><a href="/javascript/symbols.html" class="sidebar-link">Symbols</a></li><li><a href="/javascript/transpiling.html" class="sidebar-link">Transpiling</a></li><li><a href="/javascript/automatic-semicolon-insertion-asi.html" class="sidebar-link">Automatic Semicolon Insertion - ASI</a></li><li><a href="/javascript/localization.html" class="sidebar-link">Localization</a></li><li><a href="/javascript/geolocation.html" class="sidebar-link">Geolocation</a></li><li><a href="/javascript/indexeddb.html" class="sidebar-link">IndexedDB</a></li><li><a href="/javascript/modularization-techniques.html" class="sidebar-link">Modularization Techniques</a></li><li><a href="/javascript/proxy.html" class="sidebar-link">Proxy</a></li><li><a href="/javascript/postmessage-and-messageevent.html" class="sidebar-link">.postMessage() and MessageEvent</a></li><li><a href="/javascript/weakmap.html" class="sidebar-link">WeakMap</a></li><li><a href="/javascript/weakset.html" class="sidebar-link">WeakSet</a></li><li><a href="/javascript/escape-sequences.html" class="sidebar-link">Escape Sequences</a></li><li><a href="/javascript/behavioral-design-patterns.html" class="sidebar-link">Behavioral Design Patterns</a></li><li><a href="/javascript/server-sent-events.html" class="sidebar-link">Server-sent events</a></li><li><a href="/javascript/async-functions-async-await.html" aria-current="page" class="active sidebar-link">Async functions (async/await)</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/javascript/async-functions-async-await.html#introduction" class="sidebar-link">Introduction</a></li><li class="sidebar-sub-header"><a href="/javascript/async-functions-async-await.html#await-and-operator-precedence" class="sidebar-link">Await and operator precedence</a></li><li class="sidebar-sub-header"><a href="/javascript/async-functions-async-await.html#async-functions-compared-to-promises" class="sidebar-link">Async functions compared to Promises</a></li><li class="sidebar-sub-header"><a href="/javascript/async-functions-async-await.html#looping-with-async-await" class="sidebar-link">Looping with async await</a></li><li class="sidebar-sub-header"><a href="/javascript/async-functions-async-await.html#less-indentation" class="sidebar-link">Less indentation</a></li><li class="sidebar-sub-header"><a href="/javascript/async-functions-async-await.html#simultaneous-async-parallel-operations" class="sidebar-link">Simultaneous async (parallel) operations</a></li></ul></li><li><a href="/javascript/async-iterators.html" class="sidebar-link">Async Iterators</a></li><li><a href="/javascript/how-to-make-iterator-usable-inside-async-callback-function.html" class="sidebar-link">How to make iterator usable inside async callback function</a></li><li><a href="/javascript/tail-call-optimization.html" class="sidebar-link">Tail Call Optimization</a></li><li><a href="/javascript/bitwise-operators-real-world-examples-snippets.html" class="sidebar-link">Bitwise Operators - Real World Examples (snippets)</a></li><li><a href="/javascript/tilde.html" class="sidebar-link">Tilde ~</a></li><li><a href="/javascript/using-javascript-to-get-set-css-custom-variables.html" class="sidebar-link">Using javascript to get/set CSS custom variables</a></li><li><a href="/javascript/selection-api.html" class="sidebar-link">Selection API</a></li><li><a href="/javascript/file-api-blobs-and-filereaders.html" class="sidebar-link">File API, Blobs and FileReaders</a></li><li><a href="/javascript/notifications-api.html" class="sidebar-link">Notifications API</a></li><li><a href="/javascript/vibration-api.html" class="sidebar-link">Vibration API</a></li><li><a href="/javascript/battery-status-api.html" class="sidebar-link">Battery Status API</a></li><li><a href="/javascript/fluent-api.html" class="sidebar-link">Fluent API</a></li><li><a href="/javascript/web-cryptography-api.html" class="sidebar-link">Web Cryptography API</a></li><li><a href="/javascript/security-issues.html" class="sidebar-link">Security issues</a></li><li><a href="/javascript/same-origin-policy-cross-origin-communication.html" class="sidebar-link">Same Origin Policy & Cross-Origin Communication</a></li><li><a href="/javascript/error-handling.html" class="sidebar-link">Error Handling</a></li><li><a href="/javascript/global-error-handling-in-browsers.html" class="sidebar-link">Global error handling in browsers</a></li><li><a href="/javascript/debugging.html" class="sidebar-link">Debugging</a></li><li><a href="/javascript/unit-testing-javascript.html" class="sidebar-link">Unit Testing Javascript</a></li><li><a href="/javascript/evaluating-javascript.html" class="sidebar-link">Evaluating JavaScript</a></li><li><a href="/javascript/linters-ensuring-code-quality.html" class="sidebar-link">Linters - Ensuring code quality</a></li><li><a href="/javascript/anti-patterns.html" class="sidebar-link">Anti-patterns</a></li><li><a href="/javascript/performance-tips.html" class="sidebar-link">Performance Tips</a></li><li><a href="/javascript/memory-efficiency.html" class="sidebar-link">Memory efficiency</a></li><li><a href="/javascript/reserved-keywords.html" class="sidebar-link">Reserved Keywords</a></li><li><a href="/javascript/contributors.html" class="sidebar-link">The Contributors</a></li></ul></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="async-functions-async-await"><a href="#async-functions-async-await" class="header-anchor">#</a> Async functions (async/await)</h1> <p><code>async</code> and <code>await</code> build on top of promises and generators to express asynchronous actions inline. This makes asynchronous or callback code much easier to maintain.</p> <p>Functions with the <code>async</code> keyword return a <code>Promise</code>, and can be called with that syntax.</p> <p>Inside an <code>async function</code> the <code>await</code> keyword can be applied to any <code>Promise</code>, and will cause all of the function body after the <code>await</code> to be executed after the promise resolves.</p> <h2 id="introduction"><a href="#introduction" class="header-anchor">#</a> Introduction</h2> <p>A function defined as <code>async</code> is a function that can perform asynchronous actions but still look synchronous. The way it's done is using the <code>await</code> keyword to defer the function while it waits for a <a href="http://stackoverflow.com/documentation/javascript/231/promises" target="_blank" rel="noopener noreferrer">Promise<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> to resolve or reject.</p> <p><strong>Note:</strong> Async functions are <a href="https://github.com/tc39/proposals/blob/master/finished-proposals.md" target="_blank" rel="noopener noreferrer">a Stage 4 ("Finished") proposal<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> on track to be included in the ECMAScript 2017 standard.</p> <p>For instance, using the promise-based <a href="https://developer.mozilla.org/en/docs/Web/API/Fetch_API" target="_blank" rel="noopener noreferrer">Fetch API<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">getJSON</span><span class="token punctuation">(</span><span class="token parameter">url</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">try</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token keyword">await</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// Rejections in the promise will get thrown here</span>
console<span class="token punctuation">.</span><span class="token function">error</span><span class="token punctuation">(</span>err<span class="token punctuation">.</span>message<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>An async function always returns a Promise itself, so you can use it in other asynchronous functions.</p> <h3 id="arrow-function-style"><a href="#arrow-function-style" class="header-anchor">#</a> Arrow function style</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token function-variable function">getJSON</span> <span class="token operator">=</span> <span class="token keyword">async</span> <span class="token parameter">url</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> response <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span>url<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token keyword">await</span> response<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="await-and-operator-precedence"><a href="#await-and-operator-precedence" class="header-anchor">#</a> Await and operator precedence</h2> <p>You have to keep the operator precedence in mind when using <code>await</code> keyword.</p> <p>Imagine that we have an asynchronous function which calls another asynchronous function, <code>getUnicorn()</code> which returns a Promise that resolves to an instance of class <code>Unicorn</code>. Now we want to get the size of the unicorn using the <code>getSize()</code> method of that class.</p> <p>Look at the following code:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">myAsyncFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">await</span> <span class="token function">getUnicorn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>At first sight, it seems valid, but it's not. Due to operator precedence, it's equivalent to the following:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">myAsyncFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">await</span> <span class="token punctuation">(</span><span class="token function">getUnicorn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Here we attempt to call <code>getSize()</code> method of the Promise object, which isn't what we want.</p> <p>Instead, we should use brackets to denote that we first want to wait for the unicorn, and then call <code>getSize()</code> method of the result:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">asyncFunction</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token punctuation">(</span><span class="token keyword">await</span> <span class="token function">getUnicorn</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Of course. the previous version could be valid in some cases, for example, if the <code>getUnicorn()</code> function was synchronous, but the <code>getSize()</code> method was asynchronous.</p> <h2 id="async-functions-compared-to-promises"><a href="#async-functions-compared-to-promises" class="header-anchor">#</a> Async functions compared to Promises</h2> <p><code>async</code> functions do not replace the <code>Promise</code> type; they add language keywords that make promises easier to call. They are interchangeable:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">doAsyncThing</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span>
<span class="token keyword">function</span> <span class="token function">doPromiseThing</span><span class="token punctuation">(</span><span class="token parameter">input</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">r<span class="token punctuation">,</span> x</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token operator">...</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token comment">// Call with promise syntax</span>
<span class="token function">doAsyncThing</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">a</span> <span class="token operator">=></span> <span class="token function">doPromiseThing</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">b</span> <span class="token operator">=></span> <span class="token operator">...</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token parameter">ex</span> <span class="token operator">=></span> <span class="token operator">...</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// Call with await syntax</span>
<span class="token keyword">try</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> a <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">doAsyncThing</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> b <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">doPromiseThing</span><span class="token punctuation">(</span>a<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token operator">...</span>
<span class="token punctuation">}</span>
<span class="token keyword">catch</span><span class="token punctuation">(</span>ex<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token punctuation">}</span>
</code></pre></div><p>Any function that uses chains of promises can be rewritten using <code>await</code>:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">newUnicorn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">'unicorn.json'</span><span class="token punctuation">)</span> <span class="token comment">// fetch unicorn.json from server</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">responseCurrent</span> <span class="token operator">=></span> responseCurrent<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment">// parse the response as JSON</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">unicorn</span> <span class="token operator">=></span>
<span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">'new/unicorn'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token comment">// send a request to 'new/unicorn' </span>
method<span class="token operator">:</span> <span class="token string">'post'</span><span class="token punctuation">,</span> <span class="token comment">// using the POST method</span>
body<span class="token operator">:</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span><span class="token punctuation">{</span>unicorn<span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// pass the unicorn to the request body</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">responseNew</span> <span class="token operator">=></span> responseNew<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span><span class="token parameter">json</span> <span class="token operator">=></span> json<span class="token punctuation">.</span>success<span class="token punctuation">)</span> <span class="token comment">// return success property of response</span>
<span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span><span class="token parameter">err</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Error creating unicorn:'</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><p>The function can be rewritten using <code>async</code> / <code>await</code> as follows:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">newUnicorn</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">try</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> responseCurrent <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">'unicorn.json'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// fetch unicorn.json from server</span>
<span class="token keyword">const</span> unicorn <span class="token operator">=</span> <span class="token keyword">await</span> responseCurrent<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// parse the response as JSON</span>
<span class="token keyword">const</span> responseNew <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">fetch</span><span class="token punctuation">(</span><span class="token string">'new/unicorn'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token comment">// send a request to 'new/unicorn'</span>
method<span class="token operator">:</span> <span class="token string">'post'</span><span class="token punctuation">,</span> <span class="token comment">// using the POST method</span>
body<span class="token operator">:</span> <span class="token constant">JSON</span><span class="token punctuation">.</span><span class="token function">stringify</span><span class="token punctuation">(</span><span class="token punctuation">{</span>unicorn<span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// pass the unicorn to the request body</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> json <span class="token operator">=</span> <span class="token keyword">await</span> responseNew<span class="token punctuation">.</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> json<span class="token punctuation">.</span>success <span class="token comment">// return success property of response</span>
<span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Error creating unicorn:'</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>This <code>async</code> variant of <code>newUnicorn()</code> appears to return a <code>Promise</code>, but really there were multiple <code>await</code> keywords. Each one returned a <code>Promise</code>, so really we had a collection of promises rather than a chain.</p> <p>In fact we can think of it as a <code>function*</code> generator, with each <code>await</code> being a <code>yield new Promise</code>. However, the results of each promise are needed by the next to continue the function. This is why the additional keyword <code>async</code> is needed on the function (as well as the <code>await</code> keyword when calling the promises) as it tells Javascript to automatically creates an observer for this iteration. The <code>Promise</code> returned by <code>async function newUnicorn()</code> resolves when this iteration completes.</p> <p>Practically, you don't need to consider that; <code>await</code> hides the promise and <code>async</code> hides the generator iteration.</p> <p>You can call <code>async</code> functions as if they were promises, and <code>await</code> any promise or any <code>async</code> function. You don't need to <code>await</code> an async function, just as you can execute a promise without a <code>.then()</code>.</p> <p>You can also use an <code>async</code> <a href="https://en.wikipedia.org/wiki/Immediately-invoked_function_expression" target="_blank" rel="noopener noreferrer">IIFE<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> if you want to execute that code immediately:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">await</span> <span class="token function">makeCoffee</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'coffee is ready!'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre></div><h2 id="looping-with-async-await"><a href="#looping-with-async-await" class="header-anchor">#</a> Looping with async await</h2> <p>When using async await in loops, you might encounter some of these problems.</p> <p>If you just try to use await inside <code>forEach</code>, this will throw an <code>Unexpected token</code> error.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">(</span><span class="token keyword">async</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
data <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
data<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">e</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> i <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">somePromiseFn</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>This comes from the fact that you've erroneously seen the arrow function as a block. The <code>await</code> will be in the context of the callback function, which is not <code>async</code>.<br>
The interpreter protects us from making the above error, but if you add <code>async</code> to the <code>forEach</code> callback no errors get thrown. You might think this solves the problem, but it won't work as expected.</p> <p>Example:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">(</span><span class="token keyword">async</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
data <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
data<span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token keyword">async</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> i <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">somePromiseFn</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'this will print first'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>This happens because the callback async function can only pause itself, not the parent async function.</p> <blockquote></blockquote> <p>You could write an asyncForEach function that returns a promise and then you could something like
`await asyncForEach(async (e) => await somePromiseFn(e), data )`
Basically you return a promise that resolves when all the callbacks are awaited and done.
But there are better ways of doing this, and that is to just use a loop.</p> <p>You can use a <code>for-of</code> loop or a <code>for/while</code> loop, it doesn't really matter which one you pick.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">(</span><span class="token keyword">async</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
data <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> e <span class="token keyword">of</span> data<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> i <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">somePromiseFn</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'this will print last'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>But there's another catch. This solution will wait for each call to <code>somePromiseFn</code> to complete before iterating over the next one.<br>
This is great if you actually want your <code>somePromiseFn</code> invocations to be executed in order but if you want them to run concurrently, you will need to <code>await</code> on <code>Promise.all</code>.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token punctuation">(</span><span class="token keyword">async</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
data <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> p <span class="token operator">=</span> <span class="token keyword">await</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token keyword">async</span><span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">await</span> <span class="token function">somePromiseFn</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token operator">...</span>p<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p><code>Promise.all</code> receives an array of promises as its only parameter and returns a promise. When all of the promises in the array are resolved, the returned promise is also resolved. We <code>await</code> on that promise and when it's resolved all our values are available.</p> <p>The above examples are fully runnable. The <code>somePromiseFn</code> function can be made as an async echo function with a timeout.
You can try out the examples in the <a href="https://babeljs.io/repl" target="_blank" rel="noopener noreferrer">babel-repl<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> with at least the <code>stage-3</code> preset and look at the output.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">somePromiseFn</span><span class="token punctuation">(</span><span class="token parameter">n</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">res<span class="token punctuation">,</span> rej</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token function">res</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">250</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre></div><h2 id="less-indentation"><a href="#less-indentation" class="header-anchor">#</a> Less indentation</h2> <p>With promises:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">function</span> <span class="token function">doTheThing</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> <span class="token function">doOneThing</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>doAnother<span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">then</span><span class="token punctuation">(</span>doSomeMore<span class="token punctuation">)</span>
<span class="token punctuation">.</span><span class="token function">catch</span><span class="token punctuation">(</span>handleErrors<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre></div><p>With async functions:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">doTheThing</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">try</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> one <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">doOneThing</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> another <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">doAnother</span><span class="token punctuation">(</span>one<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">return</span> <span class="token keyword">await</span> <span class="token function">doSomeMore</span><span class="token punctuation">(</span>another<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token function">handleErrors</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Note how the return is at the bottom, and not at the top, and you use the language's native error-handling mechanics (<code>try/catch</code>).</p> <h2 id="simultaneous-async-parallel-operations"><a href="#simultaneous-async-parallel-operations" class="header-anchor">#</a> Simultaneous async (parallel) operations</h2> <p>Often you will want to perform asynchronous operations in parallel. There is direct syntax that supports this in the <code>async</code>/<code>await</code> proposal, but since <code>await</code> will wait for a promise, you can wrap multiple promises together in <code>Promise.all</code> to wait for them:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// Not in parallel</span>
<span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">getFriendPosts</span><span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
friendIds <span class="token operator">=</span> <span class="token keyword">await</span> db<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"friends"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>user<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>id<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
friendPosts <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">let</span> id <span class="token keyword">in</span> friendIds<span class="token punctuation">)</span> <span class="token punctuation">{</span>
friendPosts <span class="token operator">=</span> friendPosts<span class="token punctuation">.</span><span class="token function">concat</span><span class="token punctuation">(</span> <span class="token keyword">await</span> db<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"posts"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>user<span class="token operator">:</span> id<span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">// etc.</span>
<span class="token punctuation">}</span>
</code></pre></div><p>This will do each query to get each friend's posts serially, but they can be done simultaneously:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// In parallel</span>
<span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">getFriendPosts</span><span class="token punctuation">(</span><span class="token parameter">user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
friendIds <span class="token operator">=</span> <span class="token keyword">await</span><span class="token punctuation">.</span>db<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"friends"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>user<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>id<span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
friendPosts <span class="token operator">=</span> <span class="token keyword">await</span> Promise<span class="token punctuation">.</span><span class="token function">all</span><span class="token punctuation">(</span> friendIds<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token parameter">id</span> <span class="token operator">=></span>
db<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string">"posts"</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>user<span class="token operator">:</span> id<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// etc.</span>
<span class="token punctuation">}</span>
</code></pre></div><p>This will loop over the list of IDs to create an array of promises. <code>await</code> will wait for <strong>all</strong> promises to be complete. <code>Promise.all</code> combines them into a single promise, but they are done in parallel.</p> <h4 id="syntax"><a href="#syntax" class="header-anchor">#</a> Syntax</h4> <li>async function foo() {<br>
...<br>
await asyncCall()<br>
}</li>
- async function() { ... }
- async() => { ... }
<li>(async () => {<br>
const data = await asyncCall()<br>
console.log(data)
})()</li> <h4 id="remarks"><a href="#remarks" class="header-anchor">#</a> Remarks</h4> <p>Async functions are a syntactic sugar over promises and generators. They help you make your code more readable, maintainable, easier to catch errors in, and with fewer levels of indentation.</p></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/devtut/generate/edit/master/docs/javascript/async-functions-async-await.md" target="_blank" rel="noopener noreferrer">Edit this page on GitHub</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <!----></footer> <div class="page-nav"><p class="inner"><span class="prev">
←
<a href="/javascript/server-sent-events.html" class="prev">
Server-sent events
</a></span> <span class="next"><a href="/javascript/async-iterators.html">
Async Iterators
</a>
→
</span></p></div> </main></div><div class="global-ui"><!----></div></div>
<script src="/assets/js/app.1779e102.js" defer></script><script src="/assets/js/3.2cfa8016.js" defer></script><script src="/assets/js/1704.2ef114e8.js" defer></script>
</body>
</html>