One common pattern we’ll see with asynchronous programming is multiple operations which depend on each other to execute or that must be executed in a certain order. We might make one request to a database and use the data returned to us to make another request and so on! Let’s illustrate this with another cleaning example, washing clothes:
We take our dirty clothes and put them in the washing machine. If the clothes are cleaned, then we’ll want to put them in the dryer. After the dryer runs, if the clothes are dry, then we can fold them and put them away.
This process of chaining promises together is called composition. Promises are designed with composition in mind! Here’s a simple promise chain in code:
firstPromiseFunction() .then((firstResolveVal) => { return secondPromiseFunction(firstResolveVal); }) .then((secondResolveVal) => { console.log(secondResolveVal); });
Let’s break down what’s happening in the example:
- We invoke a function
firstPromiseFunction()
which returns a promise. - We invoke
.then()
with an anonymous function as the success handler. - Inside the success handler we return a new promise— the result of invoking a second function,
secondPromiseFunction()
with the first promise’s resolved value. - We invoke a second
.then()
to handle the logic for the second promise settling. - Inside that
.then()
, we have a success handler which will log the second promise’s resolved value to the console.
In order for our chain to work properly, we had to return
the promise secondPromiseFunction(firstResolveVal)
. This ensured that the return value of the first .then()
was our second promise rather than the default return of a new promise with the same settled value as the initial.
Let’s write some promise chains!
Instructions
Take a look at the provided code. We require in three functions: checkInventory()
, processPayment()
, shipOrder()
. These functions each return a promise.
checkInventory()
expects an order
argument and returns a promise. If there are enough items in stock to fill the order, the promise will resolve to an array. The first element in the resolved value array will be the same order
and the second element will be the total cost of the order as a number.
processPayment()
expects an array argument with the order
as the first element and the purchase total as the second. This function returns a promise. If there is a large enough balance on the giftcard associated with the order, it will resolve to an array. The first element in the resolved value array will be the same order
and the second element will be a tracking number.
shipOrder()
expects an array argument with the order
as the first element and a tracking number as the second. It returns a promise which resolves to a string confirming the order has shipped.
If you’d like, look at the library.js file to see how these functions work. Press “Check Work” when you’re ready to move on to the next checkpoint.
We set up a promise chain but it’s missing a couple important lines of code to make it function properly.
We invoked checkInventory()
with order
and chained a .then()
function to it. This .then()
has an anonymous function as its success handler, but it’s missing a return
statement.
The success handler should return a processPayment()
promise.
We have a second .then()
function on the chain. This .then()
also has an anonymous function as its success handler and is missing a return
statement.
The success handler should return a shipOrder()
promise.
Type node app.js
in the terminal and hit enter.