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();