Recipe 1.3
Chaining Promises
This demo makes multiple asynchronous calls and builds a Promise
chain. Each Promise
success handler
returns a new Promise
, which forms the chain. It simulates a sequence of network requests.
First, a user is loaded using the getUser
function. Once the user object is returned, it loads the user’s blog posts
via the getPostTitles
function, and finally renders them when the chain is complete.
Demo
Blog Posts
Loading...
Loading Posts
Code
JavaScript
/**
* Loads the post titles for a given user ID.
* @param userId the ID of the user whose posts you want to load
* @returns a Promise that resolves to an array of post titles
*/
function getPostTitles(userId) {
console.log('Getting user');
return getUser(userId)
// Callback is called with the loaded user object
.then(user => {
console.log(`Getting posts for ${user.name}`);
// This `Promise` is also returned from `.then`
return getPosts(user);
})
// Calling `then` on the `getPosts` `Promise`
.then(posts => {
// Returns another Promise that will resolve to an array of post titles
return posts.map(post => post.title);
})
// Called if either getUser or getPosts are rejected
.catch(error => {
console.error('Error loading data:', error);
});
}
const list = document.querySelector('#posts');
getPostTitles(1)
.then(postTitles => {
document.querySelector('#loader').remove();
postTitles.forEach(title => {
const item = document.createElement('li');
item.className = 'list-group-item';
item.textContent = title;
list.appendChild(item);
});
});
// Simulates some functions that would, in real life,
// make network requests.
function getUser(id) {
return new Promise(resolve => {
setTimeout(() => {
resolve({
name: 'Olivia Anderson'
});
}, 1000);
});
}
function getPosts(user) {
return new Promise(resolve => {
setTimeout(() => {
resolve([
{ title: 'Mastering JavaScript Fundamentals: A Comprehensive Guide'},
{ title: 'Supercharge Your Web Development with JavaScript Frameworks' },
{ title: 'Building Interactive Web Applications with JavaScript and DOM Manipulation' },
]);
}, 2000);
});
}
HTML
<h3>Blog Posts</h3>
<div id="loader" class="text-center m-4">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
<div>Loading Posts</div>
</div>
<ul id="posts" class="list-group border-0"></ul>