JavaScript & TypeScriptМодуль 5: Асинхронность
Async/Await
Современный синтаксис для асинхронного кода
Цель урока
В этом уроке ты научишься:
- Использовать async/await
- Обрабатывать ошибки
- Выполнять параллельные операции
Основы
async функция
async function getData() {
return "Данные";
}
// Возвращает Promise
getData().then(result => console.log(result)); // "Данные"await
Приостанавливает выполнение до разрешения промиса:
async function getData() {
let result = await fetch("/api/data");
let data = await result.json();
return data;
}Важно
await можно использовать только внутри async функции.
Сравнение с промисами
Промисы
function loadUser(id) {
return fetch(`/api/users/${id}`)
.then(response => response.json())
.then(user => fetch(`/api/posts?userId=${user.id}`))
.then(response => response.json())
.then(posts => {
console.log(posts);
});
}Async/await
async function loadUser(id) {
let response = await fetch(`/api/users/${id}`);
let user = await response.json();
let postsResponse = await fetch(`/api/posts?userId=${user.id}`);
let posts = await postsResponse.json();
console.log(posts);
}Обработка ошибок
try/catch
async function getData() {
try {
let response = await fetch("/api/data");
let data = await response.json();
return data;
} catch (error) {
console.log("Ошибка:", error.message);
return null;
}
}finally
async function getData() {
try {
let data = await fetch("/api/data");
return data;
} catch (error) {
console.log("Ошибка");
} finally {
console.log("Завершено");
}
}Параллельное выполнение
Последовательно (медленно)
async function loadData() {
let users = await fetch("/api/users").then(r => r.json());
let posts = await fetch("/api/posts").then(r => r.json());
let comments = await fetch("/api/comments").then(r => r.json());
return { users, posts, comments };
}
// Время: T1 + T2 + T3Параллельно (быстро)
async function loadData() {
let [users, posts, comments] = await Promise.all([
fetch("/api/users").then(r => r.json()),
fetch("/api/posts").then(r => r.json()),
fetch("/api/comments").then(r => r.json())
]);
return { users, posts, comments };
}
// Время: max(T1, T2, T3)Стрелочные async функции
const getData = async () => {
let result = await fetch("/api/data");
return result.json();
};
// В методах
const obj = {
async load() {
return await fetch("/api/data");
}
};
// В callback
const results = await Promise.all(
urls.map(async url => {
let response = await fetch(url);
return response.json();
})
);Циклы с await
for...of
async function processItems(items) {
for (let item of items) {
await processItem(item);
}
}Параллельная обработка
async function processItems(items) {
await Promise.all(
items.map(item => processItem(item))
);
}Выбор подхода
Используй for...of для последовательной обработки, Promise.all для параллельной.
Top-level await
В модулях можно использовать await на верхнем уровне:
// module.js
let response = await fetch("/api/config");
export let config = await response.json();Практические примеры
Повторные попытки
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
return await fetch(url);
} catch (error) {
if (i === retries - 1) throw error;
await delay(1000 * (i + 1));
}
}
}Таймаут
async function fetchWithTimeout(url, timeout = 5000) {
let controller = new AbortController();
let timeoutId = setTimeout(() => controller.abort(), timeout);
try {
let response = await fetch(url, { signal: controller.signal });
return response;
} finally {
clearTimeout(timeoutId);
}
}Практика
Задание 1: Базовый async/await
Задача: Создай async функцию с задержкой.
Loading...
Ваш вывод:
Задание 2: Обработка ошибок
Задача: Обработай ошибку с помощью try/catch.
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
Ошибка: Что-то пошло не так Завершено
Задание 3: Параллельное выполнение
Задача: Выполни 3 операции параллельно.
Запустите код для проверки
Loading...
Ваш вывод:
Ожидаемый результат:
[1,2,3]
Проверь себя
- Что возвращает async функция?
- Как обработать ошибку в async/await?
- Как выполнить операции параллельно?