Chapter 3
Any callbacks registered after a promise was resolved (or rejected) will
be resolved (or rejected) with the same result (or failure reason) as the
initial one.
Asynchronous action chaining
While aggregating callbacks is nice, the real power of the Promise API lies in its
ability to mimic the synchronous function invocations in the asynchronous world.
Continuing our pizza example let's imagine that this time we are invited to our
friends for a pizza. Our hosts will order a pizza and upon order arrival they will
nicely slice and serve it. There is a chain of asynchronous events here: firstly a
pizza needs to be delivered, and only then prepared for serving. There are also
two promises that need to be resolved before we can enjoy a meal: a restaurant is
promising a delivery and our hosts are promising that a delivered pizza will be
sliced and served. Let's see the code modeling this situation:
it('should illustrate successful promise chaining', function () {
var slice = function(pizza) {
return "sliced "+pizza;
};
pizzaPit.takeOrder('Margherita').then(slice).then(pawel.eat);
pizzaPit.deliverOrder();
expect($log.info.logs).toContain(['Pawel is eating delicious sliced
Margherita']);});
In the previous example, we can see a chain of promises (calls to the then method).
This construct closely resembles synchronous code:
pawel.eat(slice(pizzaPit));
Promise chaining is possible only because the then method returns
a new promise. The returned promise will be resolved with the
result of the return value of the callback.
What is even more impressive is how easy it is to deal with the error conditions.
Let's have a look at the example of the failure propagation to a person holding
onto a promise:
it('should illustrate promise rejection in chain', function () {
pizzaPit.takeOrder('Capricciosa').then(slice).then(pawel.eat,