Day 4: Exploring async and await in JavaScript

danielfeldroy

Daniel Feldroy

Posted on April 21, 2020

Day 4: Exploring async and await in JavaScript

I've always enjoyed the feeling of JavaScript promises, possibly because they feel more explicit than what I've read about await and async. I've also used await and async in Python, and have always wished async code there was implemented with JavaScript-style promises.

However, a lot of JavaScript code is written with await and async, so I decided to knuckle down and get familiar with them.

First I defined a function that returned a promise and would take some time:

function squareXAndWaitXSeconds(x) { 
  return new Promise(resolve => {
    setTimeout(() => {
      resolve(x*x); // square the result
    }, x * 1000); // delay by x seconds
  });
}
Enter fullscreen mode Exit fullscreen mode

Then I wrote an async function to call the squareXAndWaitXSeconds function:

async function addItem(y) {
  var x = await squareXAndWaitXSeconds(y); // await for the response
  console.log(x); // Log the response
}
Enter fullscreen mode Exit fullscreen mode

While this worked, it was hard to see it in action. So I used HTML for better display:

<link href="https://unpkg.com/tailwindcss@^1.2/dist/tailwind.min.css" rel="stylesheet">

<div class="container">
  <h1 class="text-4xl">Playing with Await/Async</h1>

  <!-- Use an ordered list to display the results in order they appear -->
  <ol id="result" class="list-decimal px-10">
  </ol>
</div>
Enter fullscreen mode Exit fullscreen mode

I modified the addItem function to post the result in li tags inside the ordered list:

 async function addItem(y) {
  var x = await squareXAndWaitXSeconds(y);

  // Show x  when it's done being awaited
  var li = document.createElement('li');
  li.setAttribute("class", "text-green-600");
  var sentence = `Returning ${x} from ${y} in ${y} seconds`
  var text = document.createTextNode(sentence);
  li.appendChild(text);
  result.appendChild(li);  
}
Enter fullscreen mode Exit fullscreen mode

This was much better, but I wanted a spread of numbers to evaluate. I used a for...of loop to give me better insight into what was happening:

// Count down from 5 so we can see that higher number values
// generate results after lower number values. Nothing blocks!
for (let i of [5,4,3,2,1]){
  // Show we're testing "i" immediately
  var li = document.createElement('li');
  li.setAttribute("class", "text-red-600");
  var text = document.createTextNode(`Testing ${i}`);
  li.appendChild(text);
  result.appendChild(li);

  // run the addItem() function. It won't show until i second(s) pass.
  addItem(i);
}
Enter fullscreen mode Exit fullscreen mode

In My Own Words: What's Happening

The addItem() function is labeled async, meaning that it won't block while it "waits" for the await called function (squareXandWaitXSeconds) to finish evaluating. The logic flow keeps going, hence addItem() is an asynchronous function.

The setTimeout function is used here to test this capability. In other circumstances, this could be used to render complex data on a screen (including games), call an API, or access a database.

You can see where I noodled this out in this codepen:

💖 💪 🙅 🚩
danielfeldroy
Daniel Feldroy

Posted on April 21, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related