JavaScript Async and Await

December 11, 2019


Async functions

The word “async” before a function means one simple thing: a function always returns a promise. Other values are wrapped in a resolved promise automatically.

For instance, this function returns a resolved promise with the result of 1, let’s test it:

 async function f() {
  return 1;
f().then(alert); // 1

We could explicitly return a promise, that would be the same:

 async function f() {
  return Promise.resolve(1);
f().then(alert); // 1

So, async ensures that the function returns a promise, and wraps non-promises in it.


The keyword await makes JavaScript wait until that promise settles and returns its result.

Here’s an example with a promise that resolves in 1 second:

async function f() {
  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  let result = await promise; // wait until the promise resolves (*)
  alert(result); // "done!"

The function execution “pauses” at the line (*) and resumes when the promise settles, with result becoming its result. So the code above shows “done!” in one second.

Let’s emphasize: await literally makes JavaScript wait until the promise settles, and then go on with the result. That doesn’t cost any CPU resources, because the engine can do other jobs meanwhile: execute other scripts, handle events etc.

It’s just a more elegant syntax of getting the promise result than promise.then, easier to read and write.

Can’t use await in regular functions

If we try to use await in non-async function, there would be a syntax error:

function f() {
  let promise = Promise.resolve(1);
  let result = await promise; // Syntax error

We will get this error if we do not put async before a function. As said, await only works inside an async function.

Promises chaining

  .then(response => response.json())
  .then(user => fetch(`${}`))
  .then(response => response.json())
  .then(githubUser => new Promise(function(resolve, reject) { // (*)
    let img = document.createElement('img');
    img.src = githubUser.avatar_url;
    img.className = "promise-avatar-example";

    setTimeout(() => {
      resolve(githubUser); // (**)
    }, 3000);
  // triggers after 3 seconds
  .then(githubUser => alert(`Finished showing ${}`));

Rewrite using async/await

We’ll need to replace .then calls with await. Also we should make the function async for them to work.

 async function showAvatar() {
  // read our JSON
  let response = await fetch('/article/promise-chaining/user.json');
  let user = await response.json();
  // read github user
  let githubResponse = await fetch(`${}`);
  let githubUser = await githubResponse.json();
  // show the avatar
  let img = document.createElement('img');
  img.src = githubUser.avatar_url;
  img.className = "promise-avatar-example";

  // wait 3 seconds
  await new Promise((resolve, reject) => setTimeout(resolve, 3000));

  return githubUser;


0:0:42 An example of Asynchronous JavaScript 0:7:06 Understanding Asynchronous JavaScript : The Event Loop 0:15:50 The old way : JavaScript with Callbacks 0:25:12 From Callback hell to Promises