Use Javascript Promises to clean up your code and avoid callback hell

How do Javascript Promises make code cleaner?  What is callback hell?  How do Promises make code easier to maintain?  Javascript Promises can be difficult to explain, but the benefits are easy to see.  This post shows an example system with both traditional callbacks and Javascript Promises.  You will see how Javascript Promises make the code easier to read and maintain.

Example purchase request system

The example is a purchase request system.  It manages employee requests for purchases, ensuring they meet company policy.  Users can batch multiple line items into a single purchase request.  For example a batch might contain new computer equipment for a department.  In this post I focus on displaying the purchase requests for a given user.

Purchase Request Data Types

  • Users:  users of the system have an id, username, and password.  Users own purchase requests.
  • Purchase Request:  Has an id, date, title, and total amount.  A request is a summary of the individual line items it contains.
  • Line Items:  An individual item in a purchase request.  It has an id, a title, and an amount.

These data types will be served up by a backend service.  The backend service exposes these data types through HTTP requests so the front-end code processes the results asynchronously.  The backend service exposes the following interface:

Backend Service Operations

  • Authenticate:  Accepts a username and password and returns the user object.
  • Fetch Purchase Requests:  Takes the user id and returns a list of purchase request objects.
  • Fetch Line Items:  Takes the id of a purchase request and returns the list of line items.

I feed the output of each operation into the next:

Fetching purchase request data from back-end service by using output of previous request for input of next.

Fetching Purchase Request data from back-end service

Callback Hell

Here is what the code looks like using callbacks:

Woman with a headache from too many callbacks.  She should have used Javascript Promises.

Notice the classic “Pyramid of Doom” pattern.  Since I use the output of each operation as the input to the next, I have to keep nesting callbacks.  This makes the code difficult to read.  You can also see the classic duplication of error handling as “displayError” is passed as the error callback to each operation.

Javascript Promises

Here is how the code looks using promises instead:

You can see this code is much easier to read.  The sequence of operations is clear.  First, I authenticate.  Then, fetch purchase requests and display them.  Finally, I fetch and display the line items.  If I need to add more operations, I don’t have to deepen the indentation level.  Any error that happens in the chain falls through to the error handler on the last then() statement.  This prevents the error handling duplication seen with callbacks.

Stay tuned for more promise-action!

That’s all for this post.  I will continue this series covering AngularJS Promises in detail.  You will learn how to chain multiple promises together and how to control the flow of error handling in these chains.  I teach you how to use the Angular $q service to implement functions that return promises.  I show how to aggregate the results of multiple promises so your caller can wait for all of them to complete.  You will also learn how to unit test with AngularJS Promises and how to mock services that return them.

AngularJS Promises course

I’m currently creating an AngularJS Promises Course to cover these topics and more.  The full version will contain screencasts, cheat sheets, and code exercises.  My blog posts will be a free version of the content of the course.  Subscribe to the mailing list to get email notification of new blog posts as well as a discount on the full course including:

  • Chaining & Error handling with promises
  • Functions that return promises
  • Aggregating multiple promises into one
  • Unit testing with promises