JavaScript · API · Просунутий
Паралельні запити з Promise.all
Використовуйте Promise.all для паралельних запитів API і прискорення скриптів.
Короткий вступ до теми та пояснення перед вправами (вправи нижче):
Паралельні запити з Promise.all
#Довідник Promise.all та паралельних запитів
#Вправи:
Перший Promise.all
#Використайте `Promise.all` для одночасного отримання `/api/products/` та `/api/categories/`. Виведіть загальну кількість товарів і кількість категорій.
const BASE_URL = 'https://apilearn.tukas.dev';
async function main() {
// отримати товари та категорії паралельно через Promise.all
}
main();
Рішення
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();
Отримати кілька товарів паралельно
#Отримайте товари з id 1, 2, 3, 4, 5 одночасно за допомогою `Promise.all` та `.map()`. Виведіть назву та ціну кожного.
const BASE_URL = 'https://apilearn.tukas.dev';
async function main() {
// отримати 5 товарів паралельно за допомогою .map() і Promise.all
}
main();
Рішення
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();
Авторизовані паралельні запити
#Отримайте токен, потім використайте `Promise.all` для одночасного отримання профілю та кошика. Виведіть `username` та кількість товарів у кошику.
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}` };
// отримати профіль та кошик паралельно
}
main();
Рішення
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();
Порівняти послідовний і паралельний підходи
#Отримайте товари з id 1–5 двічі: один раз послідовно через цикл, один раз паралельно через `Promise.all`. Виміряйте та виведіть час для кожного підходу за допомогою `Date.now()`.
const BASE_URL = 'https://apilearn.tukas.dev';
async function main() {
// послідовно
let start = Date.now();
// ... цикл ...
console.log('Послідовно:', Date.now() - start, 'мс');
// паралельно
start = Date.now();
// ... Promise.all ...
console.log('Паралельно:', Date.now() - start, 'мс');
}
main();
Рішення
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();
Завантажувач дашборда з Promise.all
#Напишіть функцію `loadDashboard(token)`, яка за допомогою `Promise.all` одночасно отримує товари, категорії, профіль та кошик. Виведіть зведення: username, кількість товарів, кількість категорій, кількість товарів у кошику.
const BASE_URL = 'https://apilearn.tukas.dev';
async function loadDashboard(token) {
// отримати 4 ресурси паралельно, вивести зведення
}
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();
Рішення
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();