 If you’re used to using Promises, [_async_](https://hackernoon.com/tagged/async) _/ await_ is an elegant way to make your [javascript](https://hackernoon.com/tagged/javascript) more legible. It evaluates as synchronous code but returns a promise that executes on the next [microtask](https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/). Let’s jump right in and poke around. Open up the [babel repl](https://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=false&presets=es2015%2Cstage-3&code=) and code along with me. Take a simple function and add _async_ to the beginning: **async function sayHello() { return 'hello'; }** **console.log(sayHello());** // => Promise {} You’ll see that calling this function returns a _Promise_ rather than “hello”. This is because anything returned from an _async_ function is automatically wrapped in a promise. In order to log “hello” we could do this: **sayHello() .then(str => console.log(str))** _// => 'hello'_ #### OK so what about await? First, write a function that returns a promise: **function mapLater(arr, fn, time) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(arr.map(fn)); }, time); }); }** Pretty straight forward, we map over an array after given amount of time. Now let’s use that in an _async_ function. **async function addAndMultiply(arr) { const added = await mapLater(arr, i => i + 2, 2000); const multiplied = await mapLater(added, i => i \* 2, 2000); console.log(multiplied); }** **addAndMultiply(\[1, 3, 6, 20\]);** **console.log('hello')** _// =>_ 'hello'_// 4 secs later =>_ \[6, 10, 16, 44\] You’ll see that “hello” is logged before we are returned our array. Our _async_ function is non-blocking. It’s important to note that _await_ must always be inside of an _async_ closure. Calling it in the global scope or in a function without the the async keyword will throw an error. #### Handling errors Imagine something goes wrong with our original _mapLater_ function: ... setTimeout(() => { **reject('nope');** }, time); Currently, we have no way of surfacing the error in our async _addAndMultiply_ function. When we run it, the function will fail silently. To handle errors, one solution is to use _try / catch_: async function addAndMultiply(arr) { **try {** const added = await mapLater(arr, i => i + 2, 2000); const multiplied = await mapLater(added, i => i \* 2, 2000); console.log(multiplied); **} catch(err) {** **console.error(err);** _// 2 secs later => 'nope'_ **}**} Since errors bubble up by default, another practical solution would be to handle errors at the async entry point: intricatelyNestedAsyncFunc().catch(err => console.error(err)); #### Real World Use it today! So many great libraries provide APIs that return promises. For example, if you’re using [_fetch_](https://github.com/github/fetch) to retrieve data, you can start doing things like: async function getProfileData(id) { try { **const users = await getUser(id);** ... } catch { ... } } To use _async / await_ now you’ll need to use Babel’s [_transform-async-to-generator_](https://babeljs.io/docs/plugins/transform-async-to-generator/).