JavaScript Best Practices: Async Patterns

Welcome to Part 4 of this review of the new Pluralsight course JavaScript Best Practices by Jonathan Mills.

jonathan-mills-v2

Jonathan is a JavaScript and Node.js expert working mostly in the MEAN Stack with individuals and companies to help build their technical skills to cope with the constantly changing landscape of software development.

He is also an ASP.NET insider and an international speaker focusing on JavaScript both in the browser and on the server.

Also in this series:

Part 1: Why Best Practices
Part 2: Syntax
Part 3: Behaviors
Part 4: Async Patterns
Part 5: Production Code

This module looks at ways to deal with asynchronous code in JavaScript. This is often a pain point for developers who are either haven’t done asynchronous programming before, or who have done asynchronous programming in another language and expect JavaScript to work in much the same way.

It covers good ways to write callback code, how promises work, and using Async/Await, which is coming in future version of JavaScript, today with Babel.

Also see Wes Higbee’s course Reasoning about Asynchronous JavaScript.

Callbacks

Jonathan says code with nested callbacks looks like a Christmas tree. It is difficult to read and difficult to troubleshoot.

Christmas_trees_near_Redland_Oregon

Callback hell

We see some of the code from his earlier course Building Web Applications with Node.js and Express 4.0.

This is real code and has a function within a function within a function within a function!

This is all just to check whether a user’s password is equal to another password.

Jonathan says promises won’t necessarily fix this problem for us and instead we should use named functions.

Anonymous functions are a bad habit, and they are commonplace because they are easy to do.

The refactored code works pretty much the same as before, but is now more readable.

Jonathan recommends that when we’re executing a callback, to use the return statement. Any time we call done, we call return so that we know we’re ending everything.

Promises

Promises are part of Node v4 and above, but only available in the latest browsers.

Jonathan begins by writing a generic asyncMethod that takes a message, calls setTimeout, and logs to the console after 500 milliseconds.

Next we see some suspect “christmas tree” async code with a function inside a function inside a function inside a function. Each time we are calling our asyncMethod.

We refactor this code using a script from Forbes Lindesay‘s promisejs.org

Our promise take our callback and pulls it out of our parameters. Instead of having a function as the next parameter, we use .then and use the function as the only parameter:

asyncMethod(“blah”, function () { …});

becomes

asyncMethod(“blah”).then(function () { …});

A promise essentially makes our functions “thenable” – we execute one function then we execute another function, and so one.

Jonathan says this actually looks worse than what we had before! So we see that we can refactor it using the named functions that we saw previously.

After refactoring, we have dramatically more readable small functions e.g

function findUser() {
asyncMethod(‘Find User’)
.then(validateUser)
}

But we see that we can simplify one stage further:

function findUser() {
return asyncMethod(‘Find User’)
}

We can now put all of the asynchronous logic in one place at the bottom of the JavaScript file:

asyncMethod(‘Open DB Connection’)
.then(findUser)
.then(validateUser)
.then(doStuff)

This code works the same as before, but there is not a Christmas tree in sight.

Using ES6 and Babel

This is not a course on ES6. For details on how you can learn this with Pluralsight, see the section “Once you’ve completed this learning path” in my JavaScript learning path review.

In this lesson we just see a simple introductory example:  the let keyword.

Jonathan shows us how we can install Babel and create our .babelrc.

Async – Await

In a sense, Async/Await eliminates the need for callbacks and promises.

However Async / Await is still based off of a promise.

We start with the promise code that we created earlier, and create a new function with the new keyword async written in front of it:

async function main() {
var one = await asyncMethod(‘Blah’)
.then(findUser)
//etc
}

We see Jonathan refactor this to use four variables, each of which is assigned using await.

Now this is only going to work when we have Babel correctly setup for us.

Jonathan recommends getting familiar kangax’s compatibility list if you’re not already.

A super quick explanation of the candidate stages is:

Stage 0 – maybe sometime
Stage 1 – proposed
Stage 2 – draft
Stage 3 – “pretty darn good chance of getting included…”

To use Async/Await with babel we must use the stage 3 preset. To install it:

npm install -save babel-preset-stage-3

Here’s an example .babelrc

{
“presets”: [
“stage-3”
],
“plugins”: []
}

Continue to the final part: Production Code

One thought on “JavaScript Best Practices: Async Patterns

  1. Pingback: Surrey Go User Group Meetup | Zombie Code Kill

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s