{"id":1453,"date":"2019-01-14T03:51:11","date_gmt":"2019-01-14T03:51:11","guid":{"rendered":"https:\/\/blog.hassler.ec\/wp\/?p=1453"},"modified":"2019-01-06T22:55:32","modified_gmt":"2019-01-06T22:55:32","slug":"javascript%e2%80%8a-%e2%80%8afrom-callbacks-to-async-await","status":"publish","type":"post","link":"https:\/\/blog.hassler.ec\/wp\/2019\/01\/14\/javascript%e2%80%8a-%e2%80%8afrom-callbacks-to-async-await\/","title":{"rendered":"JavaScript\u200a\u2014\u200afrom callbacks to async\/await"},"content":{"rendered":"<div class=\"section-inner sectionLayout--insetColumn\">\n<h1 id=\"d5a7\" class=\"graf graf--h3 graf--leading graf--title\"><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" style=\"font-size: 14px;\" src=\"https:\/\/cdn-images-1.medium.com\/max\/2000\/1*_GgmGZJnFec994dvCDpbWQ.jpeg\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/2000\/1*_GgmGZJnFec994dvCDpbWQ.jpeg\"><\/h1>\n<\/div>\n<div class=\"section-inner sectionLayout--fullWidth\">\n<figure id=\"6941\" class=\"graf graf--figure graf--layoutFillWidth graf-after--h3\" data-scroll=\"native\"><figcaption class=\"imageCaption\"><a class=\"markup--anchor markup--figure-anchor\" href=\"https:\/\/unsplash.com\/@thkelley\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/unsplash.com\/@thkelley\">Thomas Kelley<\/a><\/figcaption><\/figure>\n<\/div>\n<div class=\"section-inner sectionLayout--insetColumn\">\n<p id=\"b4af\" class=\"graf graf--p graf-after--figure\">JavaScript is synchronous. This means that it will execute your code block by order after&nbsp;<a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/scotch.io\/tutorials\/understanding-hoisting-in-javascript\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/scotch.io\/tutorials\/understanding-hoisting-in-javascript\">hoisting<\/a>. Before the code executes,&nbsp;<code class=\"markup--code markup--p-code\">var<\/code>&nbsp;and&nbsp;<code class=\"markup--code markup--p-code\">function<\/code>declarations are \u201choisted\u201d to the top of their scope.<\/p>\n<p id=\"a763\" class=\"graf graf--p graf-after--p\">This is an example of a synchronous code:<\/p>\n<pre id=\"9404\" class=\"graf graf--pre graf-after--p\">console.log('1')<\/pre>\n<pre id=\"bf6d\" class=\"graf graf--pre graf-after--pre\">console.log('2')<\/pre>\n<pre id=\"e2df\" class=\"graf graf--pre graf-after--pre\">console.log('3')<\/pre>\n<p id=\"9024\" class=\"graf graf--p graf-after--pre\">This code will reliably log \u201c1 2 3&#8243;.<\/p>\n<p id=\"2e8e\" class=\"graf graf--p graf-after--p\">Asynchronous requests will wait for a timer to finish or a request to respond while the rest of the code continues to execute. Then when the time is right a&nbsp;<a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Glossary\/Callback_function\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Glossary\/Callback_function\">callback&nbsp;<\/a>will spring these asynchronous requests into action.<\/p>\n<p id=\"a408\" class=\"graf graf--p graf-after--p\">This is an example of an asynchronous code:<\/p>\n<pre id=\"f44a\" class=\"graf graf--pre graf-after--p\">console.log('1')<\/pre>\n<pre id=\"c246\" class=\"graf graf--pre graf-after--pre\">setTimeout(function afterTwoSeconds() {\n  console.log('2')\n}, 2000)<\/pre>\n<pre id=\"a8b5\" class=\"graf graf--pre graf-after--pre\">console.log('3')<\/pre>\n<p id=\"7df1\" class=\"graf graf--p graf-after--pre\">This will actually log \u201c1 3 2\u201d, since the \u201c2\u201d is on a&nbsp;<code class=\"markup--code markup--p-code\">setTimeout<\/code>&nbsp;which will only execute, by this example, after two seconds. Your application does not hang waiting for the two seconds to finish. Instead it keeps executing the rest of the code and when the timeout is finished it returns to afterTwoSeconds.<\/p>\n<p id=\"c3e8\" class=\"graf graf--p graf-after--p\">You may ask \u201cWhy is this useful?\u201d or \u201cHow do I get my async code to become sync?\u201d. Hopefully I can show you the answers.<\/p>\n<h3 id=\"fdc0\" class=\"graf graf--h3 graf--startsWithDoubleQuote graf-after--p\"><strong class=\"markup--strong markup--h3-strong\">\u201cThe problem\u201d<\/strong><\/h3>\n<p id=\"ad99\" class=\"graf graf--p graf-after--h3\">Let us say our goal is to search for a GitHub user and get all the repositories of that user. The thing is we don\u2019t know the exact name of the user. So we have to list all the users with similar name and their respective repositories.<\/p>\n<p id=\"88ca\" class=\"graf graf--p graf-after--p\">Doesn\u2019t need to super fancy, something like this<\/p>\n<figure id=\"b325\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*F7hymGXdQzhikWvCYzAZOg.png\" data-width=\"1472\" data-height=\"346\" data-action=\"zoom\" data-action-value=\"1*F7hymGXdQzhikWvCYzAZOg.png\" data-scroll=\"native\"><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/1*F7hymGXdQzhikWvCYzAZOg.png\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/1*F7hymGXdQzhikWvCYzAZOg.png\"><\/div>\n<\/div><figcaption class=\"imageCaption\">So much style, wow! This is the&nbsp;\u201c<a class=\"markup--anchor markup--figure-anchor\" href=\"http:\/\/xn--https-hw3b\/\/jsfiddle.net\/fp9pk8pq\/%E2%80%9D\" target=\"_blank\" rel=\"noopener\" data-href=\"http:\/\/\u201chttps:\/\/jsfiddle.net\/fp9pk8pq\/\u201d\">f<\/a>iddle\u201d<\/figcaption><\/figure>\n<p id=\"82bd\" class=\"graf graf--p graf-after--figure\">In these examples the request code will use XHR (<a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/XMLHttpRequest\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/XMLHttpRequest\">XMLHttpRequest<\/a>). You can replace it with jQuery&nbsp;<code class=\"markup--code markup--p-code\">$.ajax<\/code>&nbsp;or the more recent native approach called&nbsp;<code class=\"markup--code markup--p-code\">fetch<\/code>. Both will give you the promises approach out of the gate.<\/p>\n<p id=\"c0d1\" class=\"graf graf--p graf-after--p\">It will be slightly changed depending on your approach but as a starter:<\/p>\n<pre id=\"ee3d\" class=\"graf graf--pre graf-after--p\">\/\/ url argument can be something like '<a class=\"markup--anchor markup--pre-anchor\" href=\"https:\/\/api.github.com\/users\/daspinola\/repos\" target=\"_blank\" rel=\"nofollow noopener\" data-href=\"https:\/\/api.github.com\/users\/daspinola\/repos\">https:\/\/api.github.com\/users\/daspinola\/repos<\/a>'<\/pre>\n<pre id=\"8f30\" class=\"graf graf--pre graf-after--pre\">function request(url) {\n  const xhr = new XMLHttpRequest();\n  xhr.timeout = 2000;\n  xhr.onreadystatechange = function(e) {\n    if (xhr.readyState === 4) {\n      if (xhr.status === 200) {\n       \/\/ Code here for the server answer when successful\n      } else {\n       \/\/ Code here for the server answer when not successful\n      }\n    }\n  }\n  xhr.ontimeout = function () {\n    \/\/ Well, it took to long do some code here to handle that\n  }\n  xhr.open('get', url, true)\n  xhr.send();\n}<\/pre>\n<p id=\"bcd8\" class=\"graf graf--p graf-after--pre\">Remember that in these examples the important part is not what the end result of the code is. Instead your goal should be to understand the differences of the approaches and how you can leverage them for your development.<\/p>\n<h3 id=\"2a21\" class=\"graf graf--h3 graf-after--p\"><strong class=\"markup--strong markup--h3-strong\">Callback<\/strong><\/h3>\n<p id=\"2b61\" class=\"graf graf--p graf-after--h3\">You can save a reference of a function in a variable when using JavaScript. Then you can use them as arguments of another function to execute later. This is our \u201ccallback\u201d.<\/p>\n<p id=\"4b92\" class=\"graf graf--p graf-after--p\">One example would be:<\/p>\n<pre id=\"7115\" class=\"graf graf--pre graf-after--p\">\/\/ Execute the function \"doThis\" with another function as parameter, in this case \"andThenThis\". doThis will execute whatever code it has and when it finishes it should have \"andThenThis\" being executed.<\/pre>\n<pre id=\"ccc0\" class=\"graf graf--pre graf-after--pre\">doThis(andThenThis)<\/pre>\n<pre id=\"2de5\" class=\"graf graf--pre graf-after--pre\">\/\/ Inside of \"doThis\" it's referenced as \"callback\" which is just a variable that is holding the reference to this function<\/pre>\n<pre id=\"f7ea\" class=\"graf graf--pre graf-after--pre\">function andThenThis() {\n  console.log('and then this')\n}<\/pre>\n<pre id=\"0cfa\" class=\"graf graf--pre graf-after--pre\">\/\/ You can name it whatever you want, \"callback\" is common approach<\/pre>\n<pre id=\"22d0\" class=\"graf graf--pre graf-after--pre\">function doThis(callback) {\n  console.log('this first')\n  \n  \/\/ the '()' is when you are telling your code to execute the function reference else it will just log the reference<\/pre>\n<pre id=\"00c3\" class=\"graf graf--pre graf-after--pre\">  callback()\n}<\/pre>\n<p id=\"bc55\" class=\"graf graf--p graf-after--pre\">Using the&nbsp;<code class=\"markup--code markup--p-code\">callback<\/code>&nbsp;to solve our problem allows us to do something like this to the&nbsp;<code class=\"markup--code markup--p-code\">request<\/code>&nbsp;function we defined earlier:<\/p>\n<pre id=\"3952\" class=\"graf graf--pre graf-after--p\">function request(url, callback) {\n  const xhr = new XMLHttpRequest();\n  xhr.timeout = 2000;\n  xhr.onreadystatechange = function(e) {\n    if (xhr.readyState === 4) {\n      if (xhr.status === 200) {\n       callback(null, xhr.response)\n      } else {\n       callback(xhr.status, null)\n      }\n    }\n  }\n  xhr.ontimeout = function () {\n   console.log('Timeout')\n  }\n  xhr.open('get', url, true)\n  xhr.send();\n}<\/pre>\n<p id=\"7d40\" class=\"graf graf--p graf-after--pre\">Our function for the request will now accept a&nbsp;<code class=\"markup--code markup--p-code\">callback<\/code>&nbsp;so that when a&nbsp;<code class=\"markup--code markup--p-code\">request<\/code>&nbsp;is made it will be called in case of error and in case of success.<\/p>\n<pre id=\"2a11\" class=\"graf graf--pre graf-after--p\">const userGet = `<a class=\"markup--anchor markup--pre-anchor\" href=\"https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`\" target=\"_blank\" rel=\"nofollow noopener noopener\" data-href=\"https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`\">https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`<\/a><\/pre>\n<pre id=\"50a2\" class=\"graf graf--pre graf-after--pre\">request(userGet, function handleUsersList(error, users) {\n  if (error) throw error\n  const list = JSON.parse(users).items<\/pre>\n<pre id=\"18aa\" class=\"graf graf--pre graf-after--pre\">  list.forEach(function(user) {\n    request(user.repos_url, function handleReposList(err, repos) {\n      if (err) throw err\n      \/\/ Handle the repositories list here\n    })\n  })\n})<\/pre>\n<p id=\"8c8d\" class=\"graf graf--p graf-after--pre\">Breaking this down:<\/p>\n<ul class=\"postList\">\n<li id=\"fb82\" class=\"graf graf--li graf-after--p\">We make a request to get a user\u2019s repositories<\/li>\n<li id=\"51bf\" class=\"graf graf--li graf-after--li\">After the request is complete we use callback&nbsp;<code class=\"markup--code markup--li-code\">handleUsersList<\/code><\/li>\n<li id=\"0cc0\" class=\"graf graf--li graf-after--li\">If there is no error then we parse our server response into an object using&nbsp;<code class=\"markup--code markup--li-code\">JSON.parse<\/code><\/li>\n<li id=\"428d\" class=\"graf graf--li graf-after--li\">Then we iterate our user list since it can have more than one<br \/>\nFor each user we request their repositories list.<br \/>\nWe will use the url that returned per user in our first response<br \/>\nWe call&nbsp;<code class=\"markup--code markup--li-code\">repos_url<\/code>as the url for our next requests or from the first response<\/li>\n<li id=\"fe9b\" class=\"graf graf--li graf-after--li\">When the request has completed the callback, we will call<br \/>\nThis will handle either its error or the response with the list of repositories for that user<\/li>\n<\/ul>\n<p id=\"a310\" class=\"graf graf--p graf-after--li\"><strong class=\"markup--strong markup--p-strong\">Note<\/strong>: Sending the error first as parameter is a common practice especially when using Node.js.<\/p>\n<p id=\"0a37\" class=\"graf graf--p graf-after--p\">A more \u201ccomplete\u201d and readable approach would be to have some error handling. We would keep the callback separate from the request execution.<\/p>\n<p id=\"9507\" class=\"graf graf--p graf-after--p\">Something like this:<\/p>\n<pre id=\"d23d\" class=\"graf graf--pre graf-after--p\">try {\n  request(userGet, handleUsersList)\n} catch (e) {\n  console.error('Request boom! ', e)\n}<\/pre>\n<pre id=\"c6d3\" class=\"graf graf--pre graf-after--pre\">function handleUsersList(error, users) {\n  if (error) throw error\n  const list = JSON.parse(users).items<\/pre>\n<pre id=\"637b\" class=\"graf graf--pre graf-after--pre\">  list.forEach(function(user) {\n    request(user.repos_url, handleReposList)\n  })\n}<\/pre>\n<pre id=\"bf62\" class=\"graf graf--pre graf-after--pre\">function handleReposList(err, repos) {\n  if (err) throw err\n  \n  \/\/ Handle the repositories list here\n  console.log('My very few repos', repos)\n}<\/pre>\n<p id=\"819e\" class=\"graf graf--p graf-after--pre\">This ends up having problems like racing and error handling issues. Racing happens when you don\u2019t control which user you will get first. We are requesting the information for all of them in case there is more than one. We are not taking an order into account. For example, user 10 can come first and user 2 last. We have a possible solution later in the article.<\/p>\n<p id=\"407b\" class=\"graf graf--p graf-after--p\">The main problem with callbacks is that maintenance and readability can become a pain. It sort of already is and the code does hardly anything. This is known as&nbsp;<strong class=\"markup--strong markup--p-strong\">callback hell<\/strong>&nbsp;which can be avoided with our next approach.<\/p>\n<figure id=\"66aa\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*3cMX1FwfBO6W5VnVcvxaWw.png\" data-width=\"1490\" data-height=\"1084\" data-action=\"zoom\" data-action-value=\"1*3cMX1FwfBO6W5VnVcvxaWw.png\" data-scroll=\"native\"><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/1*3cMX1FwfBO6W5VnVcvxaWw.png\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/1*3cMX1FwfBO6W5VnVcvxaWw.png\"><\/div>\n<\/div><figcaption class=\"imageCaption\">Image taken from&nbsp;<a class=\"markup--anchor markup--figure-anchor\" href=\"https:\/\/medium.com\/@sagish\/node-with-benefits-using-coffeescript-in-your-stack-e9754bf58668\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/medium.com\/@sagish\/node-with-benefits-using-coffeescript-in-your-stack-e9754bf58668\">here<\/a>. Callback hell at its&nbsp;best.<\/figcaption><\/figure>\n<h3 id=\"f013\" class=\"graf graf--h3 graf-after--figure\"><strong class=\"markup--strong markup--h3-strong\">Promises<\/strong><\/h3>\n<p id=\"2382\" class=\"graf graf--p graf-after--h3\">Promises you can make your code more readable. A new developer can come to the code base and see a clear order of execution to your code.<\/p>\n<p id=\"e2f8\" class=\"graf graf--p graf-after--p\">To create a promise you can use:<\/p>\n<pre id=\"5def\" class=\"graf graf--pre graf-after--p\">const myPromise = new Promise(function(resolve, reject) {\n  \n  \/\/ code here\n  \n  if (codeIsFine) {\n    resolve('fine')\n  } else {\n    reject('error')\n  }<\/pre>\n<pre id=\"995f\" class=\"graf graf--pre graf-after--pre\">})<\/pre>\n<pre id=\"eea3\" class=\"graf graf--pre graf-after--pre\">myPromise\n  .then(function whenOk(response) {\n    console.log(response)\n    return response\n  })\n  .catch(function notOk(err) {\n    console.error(err)\n  })<\/pre>\n<p id=\"8939\" class=\"graf graf--p graf-after--pre\">Let us decompose it:<\/p>\n<ul class=\"postList\">\n<li id=\"b312\" class=\"graf graf--li graf-after--p\">A promise is initialized with a&nbsp;<code class=\"markup--code markup--li-code\">function<\/code>&nbsp;that has&nbsp;<code class=\"markup--code markup--li-code\">resolve<\/code>&nbsp;and&nbsp;<code class=\"markup--code markup--li-code\">reject<\/code>statements<\/li>\n<li id=\"bccb\" class=\"graf graf--li graf-after--li\">Make your async code inside the&nbsp;<code class=\"markup--code markup--li-code\">Promise<\/code>&nbsp;function<br \/>\n<code class=\"markup--code markup--li-code\">resolve<\/code>&nbsp;when everything happens as desired<br \/>\nOtherwise&nbsp;<code class=\"markup--code markup--li-code\">reject<\/code><\/li>\n<li id=\"d537\" class=\"graf graf--li graf-after--li\">When a&nbsp;<code class=\"markup--code markup--li-code\">resolve<\/code>&nbsp;is found the<code class=\"markup--code markup--li-code\">&nbsp;.then<\/code>&nbsp;method will execute for that&nbsp;<code class=\"markup--code markup--li-code\">Promise<br \/>\n<\/code>When a&nbsp;<code class=\"markup--code markup--li-code\">reject&nbsp;<\/code>is found the&nbsp;<code class=\"markup--code markup--li-code\">.catch&nbsp;<\/code>will be triggered<\/li>\n<\/ul>\n<p id=\"cb5d\" class=\"graf graf--p graf-after--li\">Things to bear in mind:<\/p>\n<ul class=\"postList\">\n<li id=\"2853\" class=\"graf graf--li graf-after--p\"><code class=\"markup--code markup--li-code\">resolve<\/code>&nbsp;and&nbsp;<code class=\"markup--code markup--li-code\">reject<\/code>&nbsp;only accept one parameter<br \/>\n<code class=\"markup--code markup--li-code\">resolve(\u2018yey\u2019, \u2018works\u2019)<\/code>&nbsp;will only send \u2018yey\u2019 to the&nbsp;<code class=\"markup--code markup--li-code\">.then<\/code>&nbsp;callback function<\/li>\n<li id=\"08f8\" class=\"graf graf--li graf-after--li\"><span class=\"markup--quote markup--li-quote is-other\" data-creator-ids=\"anon\">If you chain multiple&nbsp;<code class=\"markup--code markup--li-code\">.then<br \/>\n<\/code>You should always add a&nbsp;<code class=\"markup--code markup--li-code\">return<\/code>&nbsp;at the end of their respective callbacks<br \/>\nElse they will execute at the same time<\/span><\/li>\n<li id=\"442d\" class=\"graf graf--li graf-after--li\">When a&nbsp;<code class=\"markup--code markup--li-code\">reject<\/code>&nbsp;is caught if you have a&nbsp;<code class=\"markup--code markup--li-code\">.then<\/code>&nbsp;chained to i<br \/>\nIt will still execute that&nbsp;<code class=\"markup--code markup--li-code\">.then<br \/>\n<\/code>You can see the&nbsp;<code class=\"markup--code markup--li-code\">.then<\/code>&nbsp;as an \u201calways executes\u201d<\/li>\n<li id=\"6378\" class=\"graf graf--li graf-after--li\">With a chain on&nbsp;<code class=\"markup--code markup--li-code\">.then<\/code>&nbsp;if an error happens on the first one<br \/>\nIt will skip subsequent&nbsp;<code class=\"markup--code markup--li-code\">.then<\/code>&nbsp;until it finds a&nbsp;<code class=\"markup--code markup--li-code\">.catch<\/code><\/li>\n<li id=\"68ae\" class=\"graf graf--li graf-after--li\">A promise has three states<br \/>\n<strong class=\"markup--strong markup--li-strong\">pending<\/strong><\/li>\n<li id=\"7fc4\" class=\"graf graf--li graf-after--li\">When waiting for a&nbsp;<code class=\"markup--code markup--li-code\">resolve<\/code>&nbsp;or&nbsp;<code class=\"markup--code markup--li-code\">reject&nbsp;<\/code>to happen\n<p><strong class=\"markup--strong markup--li-strong\">resolved&nbsp;<\/strong><br \/>\n<strong class=\"markup--strong markup--li-strong\">rejected<\/strong><\/li>\n<li id=\"ab3f\" class=\"graf graf--li graf-after--li\">Once it\u2019s in a&nbsp;<code class=\"markup--code markup--li-code\">resolved<\/code>&nbsp;or&nbsp;<code class=\"markup--code markup--li-code\">rejected<\/code>&nbsp;state<br \/>\nIt cannot be changed<\/li>\n<\/ul>\n<p id=\"8cdd\" class=\"graf graf--p graf-after--li\"><strong class=\"markup--strong markup--p-strong\">Note<\/strong>: You can create promises without the function at the moment of declarations. The way that I\u2019m showing it is only a common way of doing it.<\/p>\n<p id=\"b444\" class=\"graf graf--p graf--startsWithDoubleQuote graf-after--p\">\u201cTheory, theory, theory\u2026I\u2019m confused\u201d you may say.<\/p>\n<p id=\"6298\" class=\"graf graf--p graf-after--p\">Let\u2019s use our request example with a promise to try to clear things up:<\/p>\n<pre id=\"c4fe\" class=\"graf graf--pre graf-after--p\">function request(url) {\n  return new Promise(function (resolve, reject) {\n    const xhr = new XMLHttpRequest();\n    xhr.timeout = 2000;\n    xhr.onreadystatechange = function(e) {\n      if (xhr.readyState === 4) {\n        if (xhr.status === 200) {\n          resolve(xhr.response)\n        } else {\n          reject(xhr.status)\n        }\n      }\n    }\n    xhr.ontimeout = function () {\n      reject('timeout')\n    }\n    xhr.open('get', url, true)\n    xhr.send();\n  })\n}<\/pre>\n<p id=\"8728\" class=\"graf graf--p graf-after--pre\">In this scenario when you execute&nbsp;<code class=\"markup--code markup--p-code\">request<\/code>&nbsp;it will return something like this:<\/p>\n<figure id=\"0415\" class=\"graf graf--figure graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\"><\/div>\n<div class=\"progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded\" data-image-id=\"1*whumsNXyynNP7n4WZLZTZg.png\" data-width=\"960\" data-height=\"138\" data-action=\"zoom\" data-action-value=\"1*whumsNXyynNP7n4WZLZTZg.png\" data-scroll=\"native\"><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/1*whumsNXyynNP7n4WZLZTZg.png\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/800\/1*whumsNXyynNP7n4WZLZTZg.png\"><\/div>\n<\/div><figcaption class=\"imageCaption\">A promise pending to be resolved or&nbsp;rejected<\/figcaption><\/figure>\n<pre id=\"d495\" class=\"graf graf--pre graf-after--figure\">const userGet = `<a class=\"markup--anchor markup--pre-anchor\" href=\"https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`\" target=\"_blank\" rel=\"nofollow noopener noopener noopener\" data-href=\"https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`\">https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`<\/a><\/pre>\n<pre id=\"8b69\" class=\"graf graf--pre graf-after--pre\">const myPromise = request(userGet)<\/pre>\n<pre id=\"762f\" class=\"graf graf--pre graf-after--pre\">console.log('will be pending when logged', myPromise)<\/pre>\n<pre id=\"d6c9\" class=\"graf graf--pre graf-after--pre\">myPromise\n  .then(function handleUsersList(users) {\n    console.log('when resolve is found it comes here with the response, in this case users ', users)<\/pre>\n<pre id=\"e267\" class=\"graf graf--pre graf-after--pre\">    const list = JSON.parse(users).items\n    return Promise.all(list.map(function(user) {\n      return request(user.repos_url)\n    }))\n  })\n  .then(function handleReposList(repos) {\n    console.log('All users repos in an array', repos)\n  })\n  .catch(function handleErrors(error) {\n    console.log('when a reject is executed it will come here ignoring the then statement ', error)\n  })<\/pre>\n<p id=\"24dc\" class=\"graf graf--p graf-after--pre\">This is how we solve racing and some of the error handling problems. The code is still a bit convoluted. But its a way to show you that this approach can also create readability problems.<\/p>\n<p id=\"eb36\" class=\"graf graf--p graf-after--p\">A quick fix would be to separate the callbacks like so:<\/p>\n<pre id=\"1a55\" class=\"graf graf--pre graf-after--p\">const userGet = `<a class=\"markup--anchor markup--pre-anchor\" href=\"https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`\" target=\"_blank\" rel=\"nofollow noopener noopener noopener noopener\" data-href=\"https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`\">https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`<\/a><\/pre>\n<pre id=\"112d\" class=\"graf graf--pre graf-after--pre\">const userRequest = request(userGet)<\/pre>\n<pre id=\"e501\" class=\"graf graf--pre graf-after--pre\">\/\/ Just by reading this part out loud you have a good idea of what the code does\nuserRequest\n  .then(handleUsersList)\n  .then(repoRequest)\n  .then(handleReposList)\n  .catch(handleErrors)<\/pre>\n<pre id=\"f39c\" class=\"graf graf--pre graf-after--pre\">function handleUsersList(users) {\n  return JSON.parse(users).items\n}<\/pre>\n<pre id=\"141a\" class=\"graf graf--pre graf-after--pre\">function repoRequest(users) {\n  return Promise.all(users.map(function(user) {\n    return request(user.repos_url)\n  }))\n}<\/pre>\n<pre id=\"38a6\" class=\"graf graf--pre graf-after--pre\">function handleReposList(repos) {\n  console.log('All users repos in an array', repos)\n}<\/pre>\n<pre id=\"0464\" class=\"graf graf--pre graf-after--pre\">function handleErrors(error) {\n  console.error('Something went wrong ', error)\n}<\/pre>\n<p id=\"a9fb\" class=\"graf graf--p graf-after--pre\">By looking at what&nbsp;<code class=\"markup--code markup--p-code\">userRequest<\/code>&nbsp;is waiting in order with the&nbsp;<code class=\"markup--code markup--p-code\">.then<\/code>&nbsp;you can get a sense of what we expect of this code block. Everything is more or less separated by responsibility.<\/p>\n<p id=\"d7f7\" class=\"graf graf--p graf-after--p\">This is \u201cscratching the surface\u201d of what Promises are. To have a great insight on how they work I cannot recommend enough this&nbsp;<a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/pouchdb.com\/2015\/05\/18\/we-have-a-problem-with-promises.html\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/pouchdb.com\/2015\/05\/18\/we-have-a-problem-with-promises.html\">article<\/a>.<\/p>\n<h3 id=\"d0db\" class=\"graf graf--h3 graf-after--p\"><strong class=\"markup--strong markup--h3-strong\">Generators<\/strong><\/h3>\n<p id=\"3a53\" class=\"graf graf--p graf-after--h3\">Another approach is to use the generators. This is a bit more advance so if you are starting out feel free to jump to the next topic.<\/p>\n<p id=\"2611\" class=\"graf graf--p graf-after--p\">One use for generators is that they allow you to have async code looking like sync.<\/p>\n<p id=\"325c\" class=\"graf graf--p graf-after--p\">They are represented by a&nbsp;<code class=\"markup--code markup--p-code\">*<\/code>&nbsp;in a function and look something like:<\/p>\n<pre id=\"cd4b\" class=\"graf graf--pre graf-after--p\">function* foo() {\n  yield 1\n  const args = yield 2\n  console.log(args)\n}\nvar fooIterator = foo()<\/pre>\n<pre id=\"8362\" class=\"graf graf--pre graf-after--pre\">console.log(fooIterator.next().value) \/\/ will log 1\nconsole.log(fooIterator.next().value) \/\/ will log 2<\/pre>\n<pre id=\"4b36\" class=\"graf graf--pre graf-after--pre\">fooIterator.next('aParam') \/\/ will log the console.log inside the generator 'aParam'<\/pre>\n<p id=\"fcbd\" class=\"graf graf--p graf-after--pre\">Instead of returning with a&nbsp;<code class=\"markup--code markup--p-code\">return<\/code>, generators have a&nbsp;<code class=\"markup--code markup--p-code\">yield<\/code>&nbsp;statement. It stops the function execution until a&nbsp;<code class=\"markup--code markup--p-code\">.next<\/code>&nbsp;is made for that function iteration. It is similar to&nbsp;<code class=\"markup--code markup--p-code\">.then<\/code>&nbsp;promise that only executes when resolved comes back.<\/p>\n<p id=\"6736\" class=\"graf graf--p graf-after--p\">Our request function would look like this:<\/p>\n<pre id=\"1c8e\" class=\"graf graf--pre graf-after--p\">function request(url) {\n  return function(callback) {\n    const xhr = new XMLHttpRequest();\n    xhr.onreadystatechange = function(e) {\n      if (xhr.readyState === 4) {\n        if (xhr.status === 200) {\n          callback(null, xhr.response)\n        } else {\n          callback(xhr.status, null)\n        }\n      }\n    }\n    xhr.ontimeout = function () {\n      console.log('timeout')\n    }\n    xhr.open('get', url, true)\n    xhr.send()\n  }\n}<\/pre>\n<p id=\"afdc\" class=\"graf graf--p graf-after--pre\">We want to have the&nbsp;<code class=\"markup--code markup--p-code\">url<\/code>&nbsp;as an argument. But instead of executing the request out of the gate we want it only when we have a callback to handle the response.<\/p>\n<p id=\"e491\" class=\"graf graf--p graf-after--p\">Our&nbsp;<code class=\"markup--code markup--p-code\">generator<\/code>&nbsp;would be something like:<\/p>\n<pre id=\"e27a\" class=\"graf graf--pre graf-after--p\">function* list() {\n  const userGet = `<a class=\"markup--anchor markup--pre-anchor\" href=\"https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`\" target=\"_blank\" rel=\"nofollow noopener noopener\" data-href=\"https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`\">https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`<\/a>\n \n  const users = yield request(userGet)\n  \n  yield\n  \n  for (let i = 0; i&lt;=users.length; i++) {\n    yield request(users[i].repos_url)\n  }\n}<\/pre>\n<p id=\"e955\" class=\"graf graf--p graf-after--pre\">It will:<\/p>\n<ul class=\"postList\">\n<li id=\"b753\" class=\"graf graf--li graf-after--p\">Wait until the first&nbsp;<code class=\"markup--code markup--li-code\">request&nbsp;<\/code>is prepared<\/li>\n<li id=\"e9aa\" class=\"graf graf--li graf-after--li\">Return a&nbsp;<code class=\"markup--code markup--li-code\">function<\/code>&nbsp;reference expecting a&nbsp;<code class=\"markup--code markup--li-code\">callback<\/code>&nbsp;for the first&nbsp;<code class=\"markup--code markup--li-code\">request<br \/>\n<\/code>Our&nbsp;<code class=\"markup--code markup--li-code\">request<\/code>&nbsp;function accepts a&nbsp;<code class=\"markup--code markup--li-code\">url<br \/>\n<\/code>and returns a&nbsp;<code class=\"markup--code markup--li-code\">function<\/code>&nbsp;that expects a&nbsp;<code class=\"markup--code markup--li-code\">callback<\/code><\/li>\n<li id=\"679b\" class=\"graf graf--li graf-after--li\">Expect a&nbsp;<code class=\"markup--code markup--li-code\">users<\/code>&nbsp;to be sent in the next&nbsp;<code class=\"markup--code markup--li-code\">.next<\/code><\/li>\n<li id=\"16b8\" class=\"graf graf--li graf-after--li\">Iterate over&nbsp;<code class=\"markup--code markup--li-code\">users<\/code><\/li>\n<li id=\"1cb9\" class=\"graf graf--li graf-after--li\">Wait for a&nbsp;<code class=\"markup--code markup--li-code\">.next<\/code>&nbsp;for each of the&nbsp;<code class=\"markup--code markup--li-code\">users<\/code><\/li>\n<li id=\"52a9\" class=\"graf graf--li graf-after--li\">Return their respective callback function<\/li>\n<\/ul>\n<p id=\"d3bf\" class=\"graf graf--p graf-after--li\">So an execution of this would be:<\/p>\n<pre id=\"aa5c\" class=\"graf graf--pre graf-after--p\">try {\n  const iterator = list()\n  iterator.next().value(function handleUsersList(err, users) {\n    if (err) throw err\n    const list = JSON.parse(users).items\n    \n    \/\/ send the list of users for the iterator\n    iterator.next(list)\n    \n    list.forEach(function(user) {\n      iterator.next().value(function userRepos(error, repos) {\n        if (error) throw repos<\/pre>\n<pre id=\"c098\" class=\"graf graf--pre graf-after--pre\">        \/\/ Handle each individual user repo here\n        console.log(user, JSON.parse(repos))\n      })\n    })\n  })  \n} catch (e) {\n  console.error(e)\n}<\/pre>\n<p id=\"1212\" class=\"graf graf--p graf-after--pre\">We could separate the callback functions like we did previously. You get the deal by now, a takeaway is that we now can handle each individual user repository list individually.<\/p>\n<p id=\"e398\" class=\"graf graf--p graf-after--p\">I have mixed felling about generators. On one hand I can get a grasp of what is expected of the code by looking at the generator.<\/p>\n<p id=\"9eb4\" class=\"graf graf--p graf-after--p\">But its execution ends up having similar problems to the callback hell.<\/p>\n<p id=\"ec19\" class=\"graf graf--p graf-after--p\">Like&nbsp;<a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Statements\/async_function\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Statements\/async_function\">async\/await<\/a>, a compiler is recommended. This is because it isn\u2019t supported in older browser versions.<\/p>\n<p id=\"fde5\" class=\"graf graf--p graf-after--p\">Also it isn\u2019t that common in my experience. So it may generate confusing in codebases maintained by various developers.<\/p>\n<p id=\"c56c\" class=\"graf graf--p graf-after--p\">An awesome insight of how generators work can be found in this&nbsp;<a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/codeburst.io\/generators-in-javascript-1a7f9f884439\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/codeburst.io\/generators-in-javascript-1a7f9f884439\">article.<\/a>&nbsp;And here is another great&nbsp;<a class=\"markup--anchor markup--p-anchor\" href=\"http:\/\/chrisbuttery.com\/articles\/synchronous-asynchronous-javascript-with-es6-generators\/\" target=\"_blank\" rel=\"noopener\" data-href=\"http:\/\/chrisbuttery.com\/articles\/synchronous-asynchronous-javascript-with-es6-generators\/\">resource<\/a>.<\/p>\n<h3 id=\"2aff\" class=\"graf graf--h3 graf-after--p\"><strong class=\"markup--strong markup--h3-strong\">Async\/Await<\/strong><\/h3>\n<p id=\"6ffa\" class=\"graf graf--p graf-after--h3\">This method seems like a mix of generators with promises. You just have to tell your code what functions are to be&nbsp;<code class=\"markup--code markup--p-code\">async<\/code>. And what part of the code will have to&nbsp;<code class=\"markup--code markup--p-code\">await<\/code>&nbsp;for that&nbsp;<code class=\"markup--code markup--p-code\">promise<\/code>&nbsp;to finish.<\/p>\n<pre id=\"ad71\" class=\"graf graf--pre graf-after--p\">sumTwentyAfterTwoSeconds(10)\n  .then(result =&gt; console.log('after 2 seconds', result))<\/pre>\n<pre id=\"591a\" class=\"graf graf--pre graf-after--pre\">async function sumTwentyAfterTwoSeconds(value) {\n  const remainder = afterTwoSeconds(20)\n  return value + await remainder\n}<\/pre>\n<pre id=\"e372\" class=\"graf graf--pre graf-after--pre\"><code class=\"markup--code markup--pre-code\">function afterTwoSeconds(value) {\n  return new Promise(resolve =&gt; {\n    setTimeout(() =&gt; { resolve(value) }, 2000);\n  });\n}<\/code><\/pre>\n<p id=\"2abe\" class=\"graf graf--p graf-after--pre\">In this scenario:<\/p>\n<ul class=\"postList\">\n<li id=\"bcbf\" class=\"graf graf--li graf-after--p\">We have&nbsp;<code class=\"markup--code markup--li-code\">sumTwentyAfterTwoSeconds<\/code>&nbsp;as being an async function<\/li>\n<li id=\"98ff\" class=\"graf graf--li graf-after--li\">We tell our code to wait for the&nbsp;<code class=\"markup--code markup--li-code\">resolve<\/code>&nbsp;or&nbsp;<code class=\"markup--code markup--li-code\">reject<\/code>&nbsp;for our promise function&nbsp;<code class=\"markup--code markup--li-code\">afterTwoSeconds<\/code><\/li>\n<li id=\"598e\" class=\"graf graf--li graf-after--li\">It will only end up in the&nbsp;<code class=\"markup--code markup--li-code\">.then<\/code>&nbsp;when the&nbsp;<code class=\"markup--code markup--li-code\">await<\/code>&nbsp;operations finish<br \/>\nIn this case there is only one<\/li>\n<\/ul>\n<p id=\"ae77\" class=\"graf graf--p graf-after--li\">Applying this to our&nbsp;<code class=\"markup--code markup--p-code\">request<\/code>&nbsp;we leave it as a&nbsp;<code class=\"markup--code markup--p-code\">promise<\/code>&nbsp;as seen earlier:<\/p>\n<pre id=\"5b45\" class=\"graf graf--pre graf-after--p\">function request(url) {\n  return new Promise(function(resolve, reject) {\n    const xhr = new XMLHttpRequest();\n    xhr.onreadystatechange = function(e) {\n      if (xhr.readyState === 4) {\n        if (xhr.status === 200) {\n          resolve(xhr.response)\n        } else {\n          reject(xhr.status)\n        }\n      }\n    }\n    xhr.ontimeout = function () {\n      reject('timeout')\n    }\n    xhr.open('get', url, true)\n    xhr.send()\n  })\n}<\/pre>\n<p id=\"0607\" class=\"graf graf--p graf-after--pre\">We create our&nbsp;<code class=\"markup--code markup--p-code\">async<\/code>&nbsp;function with the needed awaits like so:<\/p>\n<pre id=\"e929\" class=\"graf graf--pre graf-after--p\">async function list() {\n  const userGet = `<a class=\"markup--anchor markup--pre-anchor\" href=\"https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`\" target=\"_blank\" rel=\"nofollow noopener\" data-href=\"https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`\">https:\/\/api.github.com\/search\/users?page=1&amp;q=daspinola&amp;type=Users`<\/a>\n  \n  const users = await request(userGet)\n  const usersList = JSON.parse(users).items\n  \n  usersList.forEach(async function (user) {\n    const repos = await request(user.repos_url)\n    \n    handleRepoList(user, repos)\n  })\n}<\/pre>\n<pre id=\"5ac2\" class=\"graf graf--pre graf-after--pre\">function handleRepoList(user, repos) {\n  const userRepos = JSON.parse(repos)\n  \n  \/\/ Handle each individual user repo here<\/pre>\n<pre id=\"3a3b\" class=\"graf graf--pre graf-after--pre\">  console.log(user, userRepos)\n}<\/pre>\n<p id=\"bdc6\" class=\"graf graf--p graf-after--pre\">So now we have an async&nbsp;<code class=\"markup--code markup--p-code\">list<\/code>&nbsp;function that will handle the requests. Another async is needed in the&nbsp;<code class=\"markup--code markup--p-code\">forEach<\/code>&nbsp;so that we have the list of<code class=\"markup--code markup--p-code\">&nbsp;repos<\/code>&nbsp;for each user to manipulate.<\/p>\n<p id=\"b8b8\" class=\"graf graf--p graf-after--p\">We call it as:<\/p>\n<pre id=\"3b5c\" class=\"graf graf--pre graf-after--p\">list()\n  .catch(e =&gt; console.error(e))<\/pre>\n<p id=\"c6c2\" class=\"graf graf--p graf-after--pre\">This and the promises approach are my favorites since the code is easy to read and change. You can read about async\/await more in depth&nbsp;<a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/davidwalsh.name\/async-await\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/davidwalsh.name\/async-await\">here<\/a>.<\/p>\n<p id=\"e87b\" class=\"graf graf--p graf-after--p\">A downside of using async\/await is that it isn\u2019t supported in the front-end by older browsers or in the back-end. You have to use the Node 8.<\/p>\n<p id=\"42ae\" class=\"graf graf--p graf-after--p\">You can use a compiler like&nbsp;<a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/babeljs.io\/\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/babeljs.io\/\">babel<\/a>&nbsp;to help solve that.<\/p>\n<h3 id=\"ad10\" class=\"graf graf--h3 graf--startsWithDoubleQuote graf-after--p\"><strong class=\"markup--strong markup--h3-strong\">\u201cSolution\u201d<\/strong><\/h3>\n<p id=\"2750\" class=\"graf graf--p graf-after--h3\">You can see the&nbsp;<a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/codepen.io\/daspinola\/pen\/EvOEKB\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/codepen.io\/daspinola\/pen\/EvOEKB\">end code<\/a>&nbsp;accomplishing our initial goal using async\/await in this snippet.<\/p>\n<p id=\"d8b8\" class=\"graf graf--p graf-after--p\">A good thing to do is to try it yourself in the various forms referenced in this article.<\/p>\n<h3 id=\"109a\" class=\"graf graf--h3 graf-after--p\"><strong class=\"markup--strong markup--h3-strong\">Conclusion<\/strong><\/h3>\n<p id=\"af89\" class=\"graf graf--p graf-after--h3\">Depending on the scenario you might find yourself using:<\/p>\n<ul class=\"postList\">\n<li id=\"0c32\" class=\"graf graf--li graf-after--p\">async\/await<\/li>\n<li id=\"7713\" class=\"graf graf--li graf-after--li\">callbacks<\/li>\n<li id=\"c19b\" class=\"graf graf--li graf-after--li\">mix<\/li>\n<\/ul>\n<p id=\"91ec\" class=\"graf graf--p graf-after--li\">It\u2019s up to you what fits your purposes. And what lets you maintain the code so that it is understandable to others and your future self.<\/p>\n<p id=\"4580\" class=\"graf graf--p graf-after--p\"><strong class=\"markup--strong markup--p-strong\">Note:<\/strong>&nbsp;Any of the approaches become slightly less verbose when using the alternatives for requests like&nbsp;<code class=\"markup--code markup--p-code\">$.ajax<\/code>&nbsp;and&nbsp;<code class=\"markup--code markup--p-code\">fetch<\/code>.<\/p>\n<p id=\"48b8\" class=\"graf graf--p graf-after--p\">Let me know what you would do different and different ways you found to make each approach more readable.<\/p>\n<p id=\"91e6\" class=\"graf graf--p graf-after--p graf--trailing\">This is Article 11 of 30. It is part of a project for publishing an article at least once a week, from idle thoughts to tutorials. Leave a comment, follow me on&nbsp;<a class=\"markup--user markup--p-user\" href=\"https:\/\/medium.com\/@daspinola\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/medium.com\/@daspinola\" data-anchor-type=\"2\" data-user-id=\"fef03c291e56\" data-action-value=\"fef03c291e56\" data-action=\"show-user-card\" data-action-type=\"hover\">Diogo Sp\u00ednola<\/a>&nbsp;and then go back to your brilliant project!<\/p>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Source:&nbsp;<strong><a href=\"https:\/\/medium.freecodecamp.org\/javascript-from-callbacks-to-async-await-1cc090ddad99\">https:\/\/medium.freecodecamp.org\/javascript-from-callbacks-to-async-await-1cc090ddad99<\/a><\/strong><\/p>\n<p>Written by<\/p>\n<div class=\"u-tableCell\"><a class=\"link u-baseColor--link avatar\" dir=\"auto\" title=\"Go to the profile of Diogo Sp\u00ednola\" href=\"https:\/\/medium.freecodecamp.org\/@daspinola?source=footer_card\" aria-label=\"Go to the profile of Diogo Sp\u00ednola\" data-action-source=\"footer_card\" data-user-id=\"fef03c291e56\" data-collection-slug=\"free-code-camp\"><img decoding=\"async\" class=\"avatar-image avatar-image--small alignleft\" src=\"https:\/\/cdn-images-1.medium.com\/fit\/c\/60\/60\/0*RfdaYWgAAk30kKdQ.jpg\" alt=\"Go to the profile of Diogo Sp\u00ednola\"><\/a><\/div>\n<div class=\"u-tableCell u-verticalAlignMiddle u-breakWord u-paddingLeft15\">\n<h3 class=\"ui-h3 u-fontSize18 u-lineHeightTighter u-marginBottom4\"><a class=\"link link--primary u-accentColor--hoverTextNormal\" dir=\"auto\" title=\"Go to the profile of Diogo Sp\u00ednola\" href=\"https:\/\/medium.freecodecamp.org\/@daspinola\" rel=\"author cc:attributionUrl\" aria-label=\"Go to the profile of Diogo Sp\u00ednola\" data-user-id=\"fef03c291e56\" data-collection-slug=\"free-code-camp\">Diogo Sp\u00ednola<\/a><\/h3>\n<p class=\"ui-body u-fontSize14 u-lineHeightBaseSans u-textColorDark u-marginBottom4\">Learning enthusiast, web developer&nbsp;<a title=\"Twitter profile for @nearsoftsolutio\" href=\"http:\/\/twitter.com\/nearsoftsolutio\" target=\"_blank\" rel=\"noopener\">@nearsoftsolutio<\/a><\/p>\n<\/div>\n<div class=\"u-tableCell \"><a class=\"link u-baseColor--link avatar avatar--roundedRectangle\" title=\"Go to freeCodeCamp.org\" href=\"https:\/\/medium.freecodecamp.org\/?source=footer_card\" aria-label=\"Go to freeCodeCamp.org\" data-action-source=\"footer_card\" data-collection-slug=\"free-code-camp\"><img decoding=\"async\" class=\"avatar-image u-size60x60 alignleft\" src=\"https:\/\/cdn-images-1.medium.com\/fit\/c\/60\/60\/1*MotlWcSa2n6FrOx3ul89kw.png\" alt=\"freeCodeCamp.org\"><\/a><\/div>\n<div class=\"u-tableCell u-verticalAlignMiddle u-breakWord u-paddingLeft15\">\n<h3 class=\"ui-h3 u-fontSize18 u-lineHeightTighter u-marginBottom4\"><a class=\"link link--primary u-accentColor--hoverTextNormal\" href=\"https:\/\/medium.freecodecamp.org\/?source=footer_card\" rel=\"collection\" data-action-source=\"footer_card\" data-collection-slug=\"free-code-camp\">freeCodeCamp.org<\/a><\/h3>\n<p class=\"ui-body u-fontSize14 u-lineHeightBaseSans u-textColorDark u-marginBottom4\">Stories worth reading about programming and technology from our open source community.<\/p>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Thomas Kelley JavaScript is synchronous. This means that it will execute your code block by order after&nbsp;hoisting. Before the code [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":91,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[12,88,48,78,44,47,29,115,116],"tags":[],"class_list":["post-1453","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-bloghassler-ec","category-design","category-front-end","category-google","category-javascript","category-medium","category-programacion","category-progresisive-web-apps","category-pwa"],"_links":{"self":[{"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/posts\/1453","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/comments?post=1453"}],"version-history":[{"count":2,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/posts\/1453\/revisions"}],"predecessor-version":[{"id":1456,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/posts\/1453\/revisions\/1456"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/media\/91"}],"wp:attachment":[{"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/media?parent=1453"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/categories?post=1453"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/tags?post=1453"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}