$q.all() - Combining promises in AngularJS

Posted by ryansouthgate on 19 Apr 2016

Using $q.all() in AngularJS couldn’t be simpler. $q is an Angular Service which facilitates running functions asynchronously. It’s based on a library (Q) by Kris Kowal.

$q.all() allows us to wait on an array (or object) of promises, $q.all() will combine these into a single promise.

One Promise

The returned promise abides by the following two rules:

  • If one promise in the array fails, the combined promise fails
  • If all promises succeed, the combined promise succeeds

Before

Before $q.all(), when wanting to wait on a number of promises, we’d have to chain them. All well and good, however the readability starts to suffer the more promises we want to wait on.

Also “chaining” doesn’t really convey what we’re trying to achieve. Chaining implies the next promise depends on the previous - in that the promises need to be run sequentially. For example:

For our example, what if we don’t really care what order they come back in, what if they’re independent service calls (the result of one call won’t be used in another)

After

Refactoring and making use of $q.all() looks like this

What we’re doing here is defining all our promises and assigning them to variables - they start right away and the results from the promises are bundled up into an array (result) and given to our $q.all().then(function(result){}) call.

Note the var promise2 where we return instantly - here we don’t need a promise. We’re able to “sneak” this into our array of promises and Angular will return it as part of the results in the then(function(results){}) of the $q.all().

This saves us creating extra overhead like creating a deferred object and resolving the value, when we don’t need to. Like below (DON’T DO THIS):

I hope this has helped demonstrate a particular pattern I’ve had success with, if you have any improvements/questions; hit me up on Twitter



comments powered by Disqus