Keeping Promises with AngularJS

As convenient as it might be to be able to try to do everything yourself, many times you need to delegate work to others. Delegating and managing work can be a job in and of itself, and this concept extends to javascript as well. There are times when you need to hand off tasks that need to be executed asynchronously. You can’t let your web page freeze and wait for the server to respond to a question. You still need to attend to the user. So you need to tell the page what to do later when it does get its answer.

One of the most common methods of accomplishing this is to provide a callback function to the code that's retrieving information. This is a set of instructions that the web page will act on when it has everything it needs to proceed. It’s a simple process that is used extensively with libraries like jQuery. But it’s not a terribly flexible method of managing this type of work. When using a callback, you are decoupling yourself from that task. You will not have any insight into the status of the task unless it’s explicitly written into the callback function. This gets to be very problematic when you have many interdependent tasks that must be delegated. Without accurate and consistent insight into their status and how they are being handled, you are forced to update code in all sorts of different places to accommodate one workflow. This is what many refer to as “callback hell.”

Promises bring order to this process of delegating and managing tasks. A promise in javascript isn’t simply a set of instructions, it is an agreement between you and the code that you’re delegating the work to. The promise is an object that can be passed around in your code, and gives you the assurance that, no matter what, you will get an answer back that can be acted upon. If the work is done successfully, unsuccessfully, or if it’s already completed, the promise will tell you how it all turns out. And you can pass it on to other parts of your code, or even to other promises. You do not need to write this into your instructions, it is just part of the agreement. In AngularJS, this functionality is provided through the $q service. It does the work of managing the overhead of the promises and can support more complex interdependencies between promises.

Here is a simple example that demonstrates how a promise could be used to handle a deferred calculation.

The following example builds upon the previous one and shows how multiple promises can be initialized at the same time. Then, by using the $q.all function, you can wait until the existing promises are fulfilled, and then post a complete message to the screen.

Promises provide an effective way to manage asynchronous tasks in javascript.  They give you more flexibility to write code the way you need it to be written, and it’s easier to read and document. Plus, you won’t be forced to do a full code review when debugging them.