JavaScript · API · Advanced
Parallel Requests with Promise.all
Use Promise.all to make concurrent API requests and speed up multi-call scripts.
Quick topic start and explanations before exercises (exercises below):
Parallel requests with Promise.all
#Promise.all and parallel fetch reference
#Exercises:
First Promise.all
#Use `Promise.all` to fetch `/api/products/` and `/api/categories/` simultaneously. Print the total product count and number of categories.
const BASE_URL = 'https://apilearn.tukas.dev';
async function main() {
// fetch products and categories in parallel with Promise.all
}
main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';
async function main() {
const [productsData, categories] = await Promise.all([
fetch(`${BASE_URL}/api/products/`).then(r => r.json()),
fetch(`${BASE_URL}/api/categories/`).then(r => r.json()),
]);
console.log(productsData.count);
console.log(categories.length);
}
main();
Fetch multiple products in parallel
#Fetch products with ids 1, 2, 3, 4, 5 all at once using `Promise.all` and `.map()`. Print the name and price of each.
const BASE_URL = 'https://apilearn.tukas.dev';
async function main() {
// fetch 5 products in parallel using .map() and Promise.all
}
main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';
async function main() {
const products = await Promise.all(
[1, 2, 3, 4, 5].map(id =>
fetch(`${BASE_URL}/api/products/${id}/`).then(r => r.json())
)
);
for (const p of products) {
console.log(p.name, p.price);
}
}
main();
Authenticated parallel requests
#Get a token, then use `Promise.all` to fetch the profile and the cart simultaneously. Print `username` and cart item count.
const BASE_URL = 'https://apilearn.tukas.dev';
async function main() {
const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
}).then(r => r.json());
const headers = { 'Authorization': `Token ${token}` };
// fetch profile and cart in parallel
}
main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';
async function main() {
const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
}).then(r => r.json());
const headers = { 'Authorization': `Token ${token}` };
const [profile, cart] = await Promise.all([
fetch(`${BASE_URL}/api/users/profile/`, { headers }).then(r => r.json()),
fetch(`${BASE_URL}/api/cart/`, { headers }).then(r => r.json()),
]);
console.log(profile.username);
console.log(cart.items.length);
}
main();
Compare sequential vs parallel
#Fetch products with ids 1–5 twice: once sequentially with a loop, once in parallel with `Promise.all`. Measure and print the time for each approach using `Date.now()`.
const BASE_URL = 'https://apilearn.tukas.dev';
async function main() {
// sequential
let start = Date.now();
// ... loop ...
console.log('Sequential:', Date.now() - start, 'ms');
// parallel
start = Date.now();
// ... Promise.all ...
console.log('Parallel:', Date.now() - start, 'ms');
}
main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';
async function main() {
// Sequential
let start = Date.now();
for (const id of [1, 2, 3, 4, 5]) {
await fetch(`${BASE_URL}/api/products/${id}/`).then(r => r.json());
}
console.log('Sequential:', Date.now() - start, 'ms');
// Parallel
start = Date.now();
await Promise.all(
[1, 2, 3, 4, 5].map(id =>
fetch(`${BASE_URL}/api/products/${id}/`).then(r => r.json())
)
);
console.log('Parallel:', Date.now() - start, 'ms');
}
main();
Dashboard loader with Promise.all
#Write a `loadDashboard(token)` function that fetches products, categories, profile, and cart all at once with `Promise.all`. Print a summary: username, product count, category count, cart item count.
const BASE_URL = 'https://apilearn.tukas.dev';
async function loadDashboard(token) {
// fetch 4 resources in parallel, print summary
}
async function main() {
const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
}).then(r => r.json());
await loadDashboard(token);
}
main();
Solution
const BASE_URL = 'https://apilearn.tukas.dev';
async function loadDashboard(token) {
const headers = { 'Authorization': `Token ${token}` };
const [productsData, categories, profile, cart] = await Promise.all([
fetch(`${BASE_URL}/api/products/`).then(r => r.json()),
fetch(`${BASE_URL}/api/categories/`).then(r => r.json()),
fetch(`${BASE_URL}/api/users/profile/`, { headers }).then(r => r.json()),
fetch(`${BASE_URL}/api/cart/`, { headers }).then(r => r.json()),
]);
console.log(`Welcome, ${profile.username}!`);
console.log(`${productsData.count} products in ${categories.length} categories`);
console.log(`Cart: ${cart.items.length} items`);
}
async function main() {
const { token } = await fetch(`${BASE_URL}/api/auth/token/`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'YOUR_USERNAME', password: 'YOUR_PASSWORD' }),
}).then(r => r.json());
await loadDashboard(token);
}
main();