This article assumes that reader is familiar with the way Promises (or Futures as they are called in other languages) work.

It was long time since I wrote an article about code, but after playing with ES7 I decided to document some of the parts, namely Async/Await. In few words: It's a syntax sugar to turn Promise chains into more or less procedural code that might look as if it's synchronised. In future when browsers and node support it natively it might even be optimised.

Let's look at this code assume that function integer returns an integer, double doubles it and increment increments it, and of course all of them are asynchronous:

const doubleAndIncrement = () => integer()
  .then(double)
  .then(increment);

This is how it's done now with promises, with async/await same function will look like this:

const doubleAndIncrement = (async function () {
  const someInt = await integer();
  const doubled = await double(someInt);
  const incremented = await increment(doubled);
  return incremented;
});

Mainly Async/Await enabled us to flatten the code, and avoid creation of anonymous functions all over the place:

// With promises
const userLogin = (payload) => {
   remoteCall(loginEndpointUrl, payload)
    .then((userData) => {
        storeCookies(userData.id, userData.token);
        return userData;
    });
    .then((userData) => {
        redirect(dashboardPath);
        return userData;
    });
}

// With Async/Await
const userLogin = (payload) => {
    const userData = await remoteCall(loginEndpointUrl, payload);
    storeCookies(userData.id, userData.token);
    redirect(dashboardPath);
    return userData;
};

Here is a code for simple example of same code with promises and async/await:

// promises.js
const DELAY = 20;

// I studied advanced mathematics in university,
// so trust me I know what I'm doing.
const one = () => 1;
// It was a long time since I used `a` and `b` as variable names.
const multiply = (a, b) => a * b;
const add = (a, b) => a + b;

// If you are unfamiliar with Promise api refer to
// http://bit.ly/mdn_promise
const promisify = (value) => new Promise((resolve, reject) => {
      setTimeout(() => resolve(value), DELAY);
});

// And let's define our services. That return random integer.
const integer = () => promisify(one());
// Double the integer.
const double = (value) => promisify(multiply(value, 2));
// And increments an integer.
const increment = (value) => promisify(add(value, 1));
// And outputs value, and passes result onward.
const output = (prefix) => (result) => {
  console.info(prefix, result);
  return result;
};

const doubleAndIncrement = () => integer()
  .then(double)
  .then(increment);

// And more complex example:
const combineTwoAndDouble = () => integer()
  .then((firstInteger) => integer()
  .then((secondInteger) => firstInteger + secondInteger)
)
  .then(double);

const run = () => {
      doubleAndIncrement()
        .then(output('Result of doubleAndIncrement:'));

  combineTwoAndDouble()
    .then(output('Result of combineTwoAndDouble:'));
};

run();

And with Async/Await

const DELAY = 20;

// I studied advanced mathematics in university,
// so trust me I know what I'm doing.
const one = () => 1;
// It was a long time since I used `a` and `b` as variable names.
const multiply = (a, b) => a * b;
const add = (a, b) => a + b;

// If you are unfamiliar with Promise api refer to
// http://bit.ly/mdn_promise
const promisify = (value) => new Promise((resolve, reject) => {
  setTimeout(() => resolve(value), DELAY);
});

// And let's define our services. That return random integer.
const integer = () => promisify(one());
// Double the integer.
const double = (value) => promisify(multiply(value, 2));
// And increments an integer.
const increment = (value) => promisify(add(value, 1));
// And outputs value, and passes result onward.
const output = (prefix) => (result) => {
  return result;
};

const doubleAndIncrement = (async function () {
  const someInt = await integer();
  const doubled = await double(someInt);
  const incremented = await increment(doubled);
  return incremented;
});

const combineTwoAndDouble = (async function () {
  const firstInteger = await integer();
  const secondInteger = await integer();
  const sum = firstInteger + secondInteger;
  const doubled = await double(sum);
  return doubled;
});

const run = (async function () {
  const doubleAndIncrementResult = await doubleAndIncrement();
  console.info('Result of doubleAndIncrement:', doubleAndIncrementResult);

  const combineTwoAndDoubleResult = await combineTwoAndDouble();
  console.info('Result of combineTwoAndDouble:', combineTwoAndDoubleResult);
});

run();

Working examples for Node 5.x can be found in this repo

I also recommend checking out following articles: