ECMAScript 2017 Async & Await

To understand async and await you need to first be familiar with Javascript’s Promise concept.

The summary is that an async function can contain await expression, and await expressions simply wait for a promise to resolve. This means that you do not need to deal with all the the Promise boilerplate, leading to cleaner code.

function doSomethingWithAPromise() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('Promise is done.');
    }, 1000);
  });
}

async function myAsyncFunction() {
  const valueFromPromise = await doSomethingWithAPromise();
  console.log(valueFromPromise);
}

console.log('Before async function.');
myAsyncFunction(); // will not log anything until the promise resolves.
console.log('After async function.');

// logs "Before async function."
//      "After async function."
//      "Promise is done."

Here the async function yields control (while it is waiting for the promise to resolve - in this case it is just waiting for a setTimeout but it could be an API call etc), and will resume when the promise resolves - this is why the log statements are not in a sequential order (because the "done" statement is only executed after the promise resolves).

Breaking the async chain

An async function always returns a promise - either explicitly or implicitly.

async function myAsyncFunction() {
  return 'banana';
}
console.log(myAsyncFunction()); // Does *not* log "banana" - logs a promise object.

Since you are returning a promise from your async function, you will also need to do something to handle waiting for your original async function’s promise to resolve too! You can’t use await unless you are in an async function, and sooner or later you’ll need to break out of that.

The solution here is just to go back to the old annoying Promise syntax of .then(result => {...}) to perform some action after your await function returns.

function doSomethingWithAPromise() {
  return new Promise(resolve => {
    setTimeout(() => {
      resolve('Promise is done.');
    }, 1000);
  });
}

async function myAsyncFunction() {
  const valueFromPromise = await doSomethingWithAPromise();
  console.log(valueFromPromise);
}

function mySyncFunction() {
  myAsyncFunction().then(() => {
    console.log('Async function has returned.');
  })
}

console.log('Before async function.');
mySyncFunction();
console.log('After async function.');

// logs "Before async function."
//      "After async function."
//      "Promise is done."
//      "Async function has returned."

Blocking/Waiting for an async function to complete

As far as I am aware, there is no built-in way to “break out” of the async chain and block execution of synchronous code while waiting for async code to complete.