Published on

Async/await

Async functions

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

async function f() {
  return 1;
}

f().then(alert); // 1

is the same as

async function f() {
  return Promise.resolve(1);
}

f().then(alert); // 1

Await

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

async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  });

  let result = await promise; // wait till the promise resolves (*)

  alert(result); // "done!"
}

f();
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(`https://api.github.com/users/${user.name}`);
  let githubUser = await githubResponse.json();

  // show the avatar
  let img = document.createElement('img');
  img.src = githubUser.avatar_url;
  img.className = "promise-avatar-example";
  document.body.append(img);

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

  img.remove();

  return githubUser;
}

showAvatar();

Error handling

async function f() {
  await Promise.reject(new Error("Whoops!"));
}

is the same as

async function f() {
  throw new Error("Whoops!");
}

We can catch that error using try..catch.

async function f() {

  try {
    let response = await fetch('https://no-such-url');
  } catch(err) {
    alert(err); // TypeError: failed to fetch
  }
}

f();

If we don't have try..catch, then the promise generated by the call of the async function f() becomes rejected. We can append .catch to handle it

async function f() {
  let response = await fetch('https://no-such-url');
}

// f() becomes a rejected promise
f().catch(alert); // TypeError: failed to fetch // (*)

References: