ES2016 (commonly refered to as ES7 or ECMAScript 7) is the next evolution of the ECMA-262 standard (commonly referred to as JavaScript), and still at an early stage.
Async functions are a new JavaScript feature, proposed as a part of the ES2016 standard and not yet supported by any browsers. They're built on top of promises.
See below for an introduction to this new feature from various authoritative sources.
Note :
Even though Async functions are commonly refered to as ES7 asynch functions
(eg. to disambiguate them from async.js or asynchronous JavaScript in general), Axel Rauschmayer recommends not calling them that, though, as a feature will only be included in the next standard once its proposal has reached stage 4.
Async functions are only at stage 3 right now. In fact, ES2016 will likely not contain async functions (as Felix Kling pointed out in the comments below).
From the stage 3 proposal :
Introduction
The introduction of promises and generators in ECMAScript presents an
opportunity to dramatically improve the language-level model for
writing asynchronous code in ECMAScript.
A similar proposal was made with Deferred Functions during
ES6 discussions. The proposal here supports the same use cases, using
similar or the same syntax, but directly building upon control flow
structures parallel to those of generators, and using promises for the
return type, instead of defining custom mechanisms.
Development of this proposal is happening at
https://github.com/tc39/ecmascript-asyncawait. Please file issues
there. Non-trivial contributions are limited to TC39 members but pull
requests for minor issues are welcome and encouraged!
Status of this proposal
This proposal was accepted into Stage 3 ("Candidate") of the
ECMAScript spec process in September 2015. The champion
intends for this proposal to be accepted into Stage 4 ("Finished") by
the end of November.
Examples
Take the following example, first written using Promises. This code
chains a set of animations on an element, stopping when there is an
exception in an animation, and returning the value produced by the
final succesfully executed animation.
function chainAnimationsPromise(elem, animations) {
let ret = null;
let p = currentPromise;
for(const anim of animations) {
p = p.then(function(val) {
ret = val;
return anim(elem);
})
}
return p.catch(function(e) {
/* ignore and keep going */
}).then(function() {
return ret;
});
}
Already with promises, the code is much improved from a straight callback style, where this sort of looping and exception handling is
challenging.
Task.js and similar libraries offer a way to use generators
to further simplify the code maintaining the same meaning:
function chainAnimationsGenerator(elem, animations) {
return spawn(function*() {
let ret = null;
try {
for(const anim of animations) {
ret = yield anim(elem);
}
} catch(e) { /* ignore and keep going */ }
return ret;
});
}
This is a marked improvement. All of the promise boilerplate above and beyond the semantic content of the code is removed, and the
body of the inner function represents user intent. However, there is
an outer layer of boilerplate to wrap the code in an additional
generator function and pass it to a library to convert to a promise.
This layer needs to be repeated in every function that uses this
mechanism to produce a promise. This is so common in typical async
Javascript code, that there is value in removing the need for the
remaining boilerplate.
With async functions, all the remaining boilerplate is removed,
leaving only the semantically meaningful code in the program text:
async function chainAnimationsAsync(elem, animations) {
let ret = null;
try {
for(const anim of animations) {
ret = await anim(elem);
}
} catch(e) { /* ignore and keep going */ }
return ret;
}
From Jake Archibald's article ES7 async functions :
Async with promises
In the HTML5Rocks article on promises, the final example show how
you'd load some JSON data for a story, then use that to fetch more
JSON data for the chapters, then render the chapters in order as soon
as they arrived.
The code looks like this:
function loadStory() {
return getJSON('story.json').then(function(story) {
addHtmlToPage(story.heading);
return story.chapterURLs.map(getJSON)
.reduce(function(chain, chapterPromise) {
return chain.then(function() {
return chapterPromise;
}).then(function(chapter) {
addHtmlToPage(chapter.html);
});
}, Promise.resolve());
}).then(function() {
addTextToPage("All done");
}).catch(function(err) {
addTextToPage("Argh, broken: " + err.message);
}).then(function() {
document.querySelector('.spinner').style.display = 'none';
});
}
Not bad, but…
This time with ES7 async functions…
async function loadStory() {
try {
let story = await getJSON('story.json');
addHtmlToPage(story.heading);
for (let chapter of story.chapterURLs.map(getJSON)) {
addHtmlToPage((await chapter).html);
}
addTextToPage("All done");
} catch (err) {
addTextToPage("Argh, broken: " + err.message);
}
document.querySelector('.spinner').style.display = 'none';
}
With async functions (full proposal), you can await
on a promise.
This halts the function in a non-blocking way, waits for the promise
to resolve & returns the value. If the promise rejects, it throws with
the rejection value, so you can deal with it using catch
.
Edit: I originally used await
within an arrow function, apparently that's not allowed so I've replaced it with a for
loop. Domenic gave me a knowledge smack-down on why await
can't be
used in arrow functions.
loadStory
returns a promise, so you can use it in other async
functions.
(async function() {
await loadStory();
console.log("Yey, story successfully loaded!");
}());
From KoaJS article The Evolution of Asynchronous JavaScript :
Generators / yield
JavaScript Generators is a relatively new concept, they were
introduced in ES6 (also known as ES2015).
Wouldn't it be nice, that when you execute your function, you could pause it at any point, calculate something else, do other things, and
then return to it, even with some value and continue?
This is exactly what generator functions do for you. When we call a
generator function it doesn't start running, we will have to iterate
through it manually.
function* foo () {
var index = 0;
while (index < 2) {
yield index++;
}
}
var bar = foo();
console.log(bar.next()); // { value: 0, done: false }
console.log(bar.next()); // { value: 1, done: false }
console.log(bar.next()); // { value: undefined, done: true }
If you want to use generators easily for writing asynchronous
JavaScript, you will need co as well.
Co is a generator based control flow goodness for Node.js and the browser, using promises, letting you write non-blocking code in a
nice-ish way.
With co
, our previous examples may look something like this:
co(function* (){
yield Something.save();
}).then(function() {
// success
})
.catch(function(err) {
//error handling
});
You may ask: what about operations running in parallel? The answer is
simpler than you may think (under the hoods it is just a
Promise.all
):
yield [Something.save(), Otherthing.save()];
Async / await
Async functions were introduced in ES7 - and currently only available
using a transpiler like babel. (disclaimer: now we are talking about
the async keyword, not the async package)
In short, with the async
keyword we can do what we are doing with
the combination of co
and generators - except the hacking.

Under the hood async
functions using Promises - this is why the
async function will return with a Promise
.