What is Async?
Async (aka asynchronous) JavaScript refers to the execution of more than one piece of code at the same time. This is great because it prevents your application from freezing up when certain code takes a long time to execute, but it can also cause issues in your code if you are expecting something to be complete when it may not be. These situations are called race conditions. Here is an example of when a function is performing asyc code and we don’t get the result we are expecting: http://codepen.io/dganoff/pen/oXLNeb. Notice the name
variable isn’t returned as “Bob”, but is instead returned as it’s initial value.
Enter: Promises
Promises allow developers to detect when asynchronous code finishes and then act on it. Instead of a function returning a value we expect, we can have it return a Promise, and then let the Promise tell us when the value is ready to use. Now let’s take a look at how Promises can fix our issue in the original example: http://codepen.io/dganoff/pen/QbNxJq. Using the built-in promise library $q that ships with Angular, we can return a Promise instead of just the name
variable. The Promise is “resolved” after the timeout finishes, which tells the promise to execute its then
method to finally return the value we originally wanted.
Real-world GitHub API Example
One of the most common uses for Promises is within a Service that makes a HTTP call and returns the response to a controller. Since HTTP calls take some time to finish, they are a prime candidate for Promises. Here’s an example of how we can use a Promise to return the HTTP response to a controller when it’s ready: http://codepen.io/dganoff/pen/zGKpzv
Advanced Promises
Let’s say you need to make a number of consecutive HTTP calls within your Service before returning the result back to the controller. The $q library has a very useful method call $q.all. This allows you to pass an array of Promises to the method and it will only execute its ‘then’ method once all Promises have been resolved. This prevents any race conditions when executing multiple HTTP calls before performing another action.
Another case where we can use multiple Promises is a technique called ‘Chaining Promises’. Sometimes within a controller, we’ll need to call one HTTP Service before another HTTP Service can be called, in case we need information from the first Service. The nice thing about $q Promises is that the Promise itself returns a Promise. This way we can have a function return one of our Services that returns a Promise and then act on that once it’s ready. If we take our GitHub API example, I can chain the ‘getGithubUserInfo’ function with another function by returning a Promise. This is what that might look like: http://codepen.io/dganoff/pen/aOmEVZ
Conclusion
Promises are a powerful tool in software development. Any web developer should have at least a basic understanding of Promises, if not a thorough grasp of the concepts discussed in this article. Please feel free to fork and edit these codepen examples to test our your own skills with Promises so you can master this critical technique.