0.4.6: Promises
Learning Objectives
JavaScript Promises allow us to program logic to run after asynchronous function calls return, e.g. network requests that take an indefinite amount of time.
Promises are an alternative to callback functions and often a "cleaner" syntax due to fewer levels of nesting.
.catch
allows us to run specified logic when our programs encounter errors in promisesPromise.all
allows us to wait on multiple promises concurrently instead of sequentially
Introduction
JavaScript Promises allow us to program logic to run after asynchronous function calls return, for example if we wanted to highlight a like button after we have saved the "like" in our database. The same logic would be possible with callback functions, but promises allow us to achieve the same functionality with at most 1 level of nesting.
The following examples use a common HTTP-request-making library called Axios. Axios is a promise-based HTTP library that allows us to make arbitrary HTTP requests in code. "Promise-based" means Axios functions return promises, allowing us to run certain logic only when the promises "resolve", i.e. when the requests are completed.
.then
.then
The function axios.get
sends a GET request and returns a promise, on which we then call the promise's .then
method to perform certain logic only when the GET request is complete, i.e. when we receive a response. 3rd-party asynchronous functions such as axios.get
often return promises for this purpose, and when unsure we can check their online documentation.
The following code sends a request, then console.log
s the response when the response is received.
The previous code can be rewritten as follows for a clearer breakdown of how .then
works.
Note that handleResponse
receives a response
parameter. Because the above promise is for an Axios request, the callback function receives an Axios response object as a parameter.
Sequential Promises
Sometimes we may wish to perform multiple network calls sequentially. For example, when a user requests to change their password, we may wish to:
Send a request to change their password
When that request is complete, send an email through an email API
Render a success message after the email is sent
.then
always returns a promise, regardless of whether the callback function passed to .then
returns nothing, a promise, or anything else. Hence we can always call .then
on the return value of any .then
call. See .then
docs for a more detailed description of this behaviour.
.catch
.catch
.catch
allows us to run specified logic when our programs encounter errors in promises. For example, if our above request to change password encountered an error such as invalid password or user had no account, we could program logic to return a graceful error message in the .catch
block. Without .catch
, our programs would crash on errors in promises.
.catch
catches errors for all promises in the promises sequence before it. Notice there is only 1 .catch
for the string of promises below.
Promise.all
Promise.all
Promise.all
allows us to wait on multiple promises concurrently instead of sequentially. For example, if I wanted to retrieve independent data to render on a page such product data and user data, I could use Promise.all
to wait for multiple database queries to all return before proceeding. Without Promise.all
we would need to wait for each of these queries sequentially using .then
.