{"id":2121,"date":"2020-11-17T20:16:52","date_gmt":"2020-11-17T12:16:52","guid":{"rendered":"https:\/\/www.techcoil.com\/blog\/?p=2121"},"modified":"2020-11-20T13:20:26","modified_gmt":"2020-11-20T05:20:26","slug":"how-to-synchronize-your-javascript-function-calls-with-async-and-await","status":"publish","type":"post","link":"https:\/\/www.techcoil.com\/blog\/how-to-synchronize-your-javascript-function-calls-with-async-and-await\/","title":{"rendered":"How to synchronize your JavaScript function calls with async and await"},"content":{"rendered":"<p>When ECMAScript 2017 was finalised in June 2017, we get the <code>async\/await<\/code> constructs that simplify synchronous JavaScript function calls.<\/p>\n<p>Therefore, you may want to use <code>async<\/code> and <code>await<\/code> to keep your JavaScript lean.<\/p>\n<p>In case you need it, this post shows how you can synchronize your JavaScript function calls with <code>async<\/code> and <code>await<\/code>.<\/p>\n<h2>Understand what <code>async<\/code> do to your JavaScript function<\/h2>\n<p>First, let us look at the <code>async<\/code> construct. We typically place the <code>async<\/code> construct in front of a JavaScript function:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nasync function add(x, y) {\r\n    return x + y;\r\n}\r\n<\/pre>\n<p>When we place the async construct before the add function, the return value is magically wrapped in a JavaScript Promise. Given that, we can call our <code>add<\/code> function in the following way:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nadd(1, 3).then(alert);\r\n<\/pre>\n<p>When the JavaScript code is ran by a compatible browser, we will see 4 appearing in an alert window.<\/p>\n<h2>Understand what <code>await<\/code> does to your JavaScript function call<\/h2>\n<p>When you put <code>await<\/code> before a <code>Promise<\/code>, you make your JavaScript interpreter wait until that Promise is able to return a result.<\/p>\n<p>For example, in the following JavaScript code segment, the <code>alert<\/code> function will only run after 1 second:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nasync function showAdditionResult() {\r\n\r\n    promiseToAdd = new Promise(function (resolve, reject) {\r\n        setTimeout(function () { \r\n            resolve(add(1, 3));\r\n        }, 1000)\r\n    });\r\n\r\n    result = await promiseToAdd; \r\n\r\n    alert(result); \r\n\r\n}\r\nshowAdditionResult();\r\n<\/pre>\n<p>This is because the <code>await<\/code> function will block the interpreter till <code>setTimeout<\/code> function performs the addition. Therefore, the <code>alert<\/code> function will make the browser show an alert window with 4 in the dialog body without fail.<\/p>\n<p>If we want to achieve similar behaviour without the <code>await<\/code> construct, then we will have to put the alert function within the <code>then()<\/code> function of <code>promiseToAdd<\/code>:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction showAdditionResult() {\r\n\r\n    promiseToAdd = new Promise(function (resolve, reject) {\r\n        setTimeout(function () { \r\n            resolve(add(1, 3));\r\n        }, 1000)\r\n    });\r\n\r\n    promiseToAdd.then(\r\n        function(result) {\r\n            alert(result); \r\n        }\r\n    ); \r\n\r\n}\r\nshowAdditionResult();\r\n<\/pre>\n<p>Indeed by comparing both versions, we can see that the <code>await<\/code> construct can help enhance the readability of synchronous JavaScript codes.<\/p>\n<h3>Uncaught SyntaxError: await is only valid in async function<\/h3>\n<p>If we use <code>await<\/code> in a regular JavaScript function, then the interpreter will throw us a syntax error.<\/p>\n<p>For example, our JavaScript interpreter will not be able to interpret the following JavaScript function:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction showAdditionResult() {\r\n\r\n    promiseToAdd = new Promise(function (resolve, reject) {\r\n        setTimeout(function () { \r\n            resolve(add(1, 3));\r\n        }, 1000)\r\n    });\r\n\r\n    result = await promiseToAdd; \r\n\r\n    alert(result); \r\n\r\n}\r\n\r\nshowAdditionResult();\r\n<\/pre>\n<p>When we attempt to run the above JavaScript codes in a Chrome browser, we will see the following error message in the console:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\r\nUncaught SyntaxError: await is only valid in async function\r\n<\/pre>\n<h2>Catch errors that may happen<\/h2>\n<p>In order to see how errors can be caught while we use the <code>await<\/code> function, let's define an <code>async<\/code> function that attempt to <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Fetch_API\" rel=\"noopener\" target=\"_blank\">fetch<\/a> from a URL:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nasync function fetchData(url) {\r\n\r\n    response = await fetch(url);\r\n    \r\n    if (response.ok) {\r\n        return response.json();\r\n    }\r\n    else {\r\n        throw new Error(response.status);\r\n    }\r\n}\r\n<\/pre>\n<p>Since <code>fetch<\/code> only reject on network failure or if anything prevented the request from completing, we explicitly throw an <code>Error<\/code> on HTTP error status.<\/p>\n<p>Given that, we try to catch Errors throw by the <code>fetchData<\/code> function. When we use the <code>await<\/code> construct, we will be able to catch errors easily. <\/p>\n<p>In order to do so, we simply wrap the function call in a try-catch block:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nasync function testFetches() {\r\n    try {\r\n        jsonData = await fetchData('https:\/\/httpbin.org\/headers');\r\n        alert(JSON.stringify(jsonData));\r\n\r\n        jsonData = await fetchData('https:\/\/httpbin.org\/status\/500');\r\n        alert(JSON.stringify(jsonData));    \r\n\r\n    } catch(err) {\r\n        alert(err);\r\n    }\r\n}\r\n\r\ntestFetches();\r\n<\/pre>\n<p>When we ran the two previous JavaScript code segments, we simulate a scenario to catch <code>Error<\/code>. <\/p>\n<p>Since a <a href=\"https:\/\/www.techcoil.com\/glossary\/http-request\/\" rel=\"noopener\" target=\"_blank\">HTTP request<\/a> made to <a href=\"https:\/\/httpbin.org\/headers\" rel=\"noopener\" target=\"_blank\">https:\/\/httpbin.org\/headers<\/a> will return a response with 200 OK, we will be able to show an alert with the JSON data from the response body. <\/p>\n<p>However, when we try to make a HTTP request to <a href=\"https:\/\/httpbin.org\/status\/500\" rel=\"noopener\" target=\"_blank\">https:\/\/httpbin.org\/status\/500<\/a>, an Error will be thrown. When that happens, the browser will show <strong>Error: 500<\/strong> in an alert window.<\/p>\n\n      <ul id=\"social-sharing-buttons-list\">\n        <li class=\"facebook\">\n          <a href=\"https:\/\/www.facebook.com\/sharer\/sharer.php?u=https%3A%2F%2Fwp.me%2Fp245TQ-yd\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n            <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Facebook.png\" alt=\"Facebook icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"twitter\">\n          <a href=\"https:\/\/twitter.com\/intent\/tweet?text=&url=https%3A%2F%2Fwp.me%2Fp245TQ-yd&via=Techcoil_com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Twitter.png\" alt=\"Twitter icon\"> Tweet\n          <\/a>\n        <\/li>\n        <li class=\"linkedin\">\n          <a href=\"https:\/\/www.linkedin.com\/shareArticle?mini=1&title=&url=https%3A%2F%2Fwp.me%2Fp245TQ-yd&source=https:\/\/www.techcoil.com\" target=\"_blank\" role=\"button\" rel=\"nofollow\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/linkedin.png\" alt=\"Linkedin icon\"> Share\n          <\/a>\n        <\/li>\n        <li class=\"pinterest\">\n          <a href=\"https:\/\/pinterest.com\/pin\/create\/button\/?url=https%3A%2F%2Fwww.techcoil.com%2Fblog%2Fwp-json%2Fwp%2Fv2%2Fposts%2F2121&description=\" class=\"pin-it-button\" target=\"_blank\" role=\"button\" rel=\"nofollow\" count-layout=\"horizontal\">\n          <img decoding=\"async\" src=\"\/ph\/img\/3rd-party\/social-icons\/Pinterest.png\" alt=\"Pinterest icon\"> Save\n          <\/a>\n        <\/li>\n      <\/ul>\n    ","protected":false},"excerpt":{"rendered":"<p>When ECMAScript 2017 was finalised in June 2017, we get the <code>async\/await<\/code> constructs that simplify synchronous JavaScript function calls.<\/p>\n<p>Therefore, you may want to use <code>async<\/code> and <code>await<\/code> to keep your JavaScript lean.<\/p>\n<p>In case you need it, this post shows how you can synchronize your JavaScript function calls with <code>async<\/code> and <code>await<\/code>.<\/p>\n","protected":false},"author":1,"featured_media":1213,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"footnotes":""},"categories":[375],"tags":[749,750,748,128],"jetpack_featured_media_url":"https:\/\/www.techcoil.com\/blog\/wp-content\/uploads\/JavaScript-Logo.gif","jetpack_shortlink":"https:\/\/wp.me\/p245TQ-yd","jetpack-related-posts":[],"jetpack_likes_enabled":true,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/2121"}],"collection":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/comments?post=2121"}],"version-history":[{"count":0,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/posts\/2121\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media\/1213"}],"wp:attachment":[{"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/media?parent=2121"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/categories?post=2121"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.techcoil.com\/blog\/wp-json\/wp\/v2\/tags?post=2121"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}