Chapter 3
Working with promises and the $q service
To learn the relatively small API exposed by the $q service, we are going to use
examples from real life, just to demonstrate that the Promise API can be applied
to any asynchronous events, and not only to XHR calls.
Learning $q service basics
Let's imagine that we want to order a pizza over the phone and have it delivered
to our home. The outcome of our pizza order can be either delivered food or a
phone call indicating problems with our order. While ordering a pizza is just a
matter of a short phone call, the actual delivery (order fulfillment) takes some time,
and is asynchronous.
To get the feeling of the Promise API, let's have a look at the pizza order, and
its successful delivery, modeled using the $q service. Firstly, we are going to
define a person that can consume a pizza, or just get disappointed when an order
is not delivered:
var Person = function (name, $log) {
this.eat = function (food) {
$log.info(name + " is eating delicious " + food);
};
this.beHungry = function (reason) {
$log.warn(name + " is hungry because: " + reason);
}
};
The Person constructor defined above can be used to produce an object containing
the eat and beHungry methods. We are going to use those methods as the success
and error callbacks, respectively.
Now, let's model a pizza ordering and fulfillment process written as a Jasmine test:
it('should illustrate basic usage of $q', function () {
var pizzaOrderFulfillment = $q.defer();
var pizzaDelivered = pizzaOrderFulfillment.promise;
pizzaDelivered.then(pawel.eat, pawel.beHungry);
pizzaOrderFulfillment.resolve('Margherita');
$rootScope.$digest();
expect($log.info.logs).toContain(['Pawel is eating delicious
Margherita']);
});