Up in the air! It's async, it's await, it's ES7!

ES7 Async/Await

In the beginning...

The common pattern for writing webservers at the time was to use processes or threads for concurrency. Some people were trying to build evented models that would work within these existing environments, but it wasn't easy.

Ryan Dahl had an important insight: if the core libraries and really the entire ecosystem isn't designed to be asynchronous/evented, you'll constantly run into blocking code that destroys performance.

Thou Shalt Be Async

And so this was a guiding principle of node and the node ecosystem. And also a source of much criticism. Both then and now, a common complaint about node is "callback hell."

You already know what this is, but there's an example on the next slide.

And again the promise version. Instead of nesting, we get a straightforward linear progression of events. Get the URL, then write a file, then log. And we can handle errors more like regular synchronous javascript.

There's one more slight complication. This function will produce a syntax error. That's because you can only use await inside of a function declared a special way.

function x(aPromise) { await aPromise }

Here's the corrected version of this simple function. We add the async keyword before our function declaration. Following the same rule, you can't have a top level await . Tonic, the program being used here, relaxes this rule since its so convenient when working in a REPL.

What does async do? Essentially, it wraps the return value of the function in a promise. Under the hood it is more or less using generators, but all of that is hidden away behind this simple syntax..

async function x(aPromise) { await aPromise }

"await" is not threads

In a language with threads, concurrency can be out of your control. Your thread can be interrupted at any time, so we need locks and other synchronization primitives.

But JavaScript's model hasn't changed, it's still single threaded. The code is only interrupted by your explicit command to "await". You can still mess up by sharing state, but that's nothing new.

await gives you explicit control over concurrency. You can combine this with powerful promise utilities like Promise.all, which will wait for every promise to finish and then finish itself, to write powerful and yet easy to understand asynchronous code.