How to Use Async Await With Node.js 8.0.0

Node.js 8.0.0 is around the corners so its a great time to learn about the shiny new async await features.

In my opinion async await can help you write easier to understand and maintainable code but it requires at least a minimal understanding of Node.js promises to use effectively.

Check out my article on promises for additional info.

async

  • When an async function is called it returns a promise.
  • When the async function returns a value the initial promise will be resolved with the returned value.
  • When the async function throws a value the initial promise will be rejected with that value.

This means you don’t have to wrap your function in a promise to use them.
You can simply use return and throw instead of resolve and reject.

Async functions return promises so they can be used with then / catch chains without having to wrap them.

In this example i had to wrap setTimeout since its not an async function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function doLater() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('done');
}, 1000);
});
}

async function chainStart(){
return await doLater();
}

doLater()
.then(val => {
console.log(val);
})
.catch( error => {
console.log(error);
});

await

The await expression causes async function execution to pause, to wait for the Promise’s resolution, and to resume the async function execution when the value is resolved. It then returns the resolved value. If the value is not a Promise, it’s converted to a resolved Promise.

If the Promise is rejected, the await expression throws the rejected value.

Basically you can replace then chains inside functions to await expressions.
The only limitation is that you can’t use it on the top level so it must be inside an async function.

Here we mock up an async function by wrapping setTimeout.
The await expressions are basically the same as then chains.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function increment(counter) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(counter + 1);
}, 1000);
});
}

async function chainStart(){
let counter = 0;
counter = await increment(counter); // 1
counter = await increment(counter); // 2
return counter;
}

chainStart()
.then(val => {
console.log(val);
})
.catch( error => {
console.log(error);
});

Iteration

Iteration can be tricky with Promises.
await can make this task easier.

Sequential iteration

1
2
3
4
5
6
7
8
async function printFiles () {
const files = await getFilePaths();

for (let file of files) {
const contents = await fs.readFile(file, 'utf8');
console.log(contents);
}
}

To read about more Node.js 8.0.0 features check out this article.