Async и await
async/await — это синтаксический сахар над промисами, который позволяет писать асинхронный код так, будто он синхронный. Он делает код проще для чтения и отладки, сохраняя при этом все преимущества промисов.
Основной синтаксис
Функция, содержащая await, должна быть помечена ключевым словом async. Такая функция всегда возвращает промис:
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
return data; // эквивалентно resolve(data)
}
Вызов этой функции:
fetchData().then(data => console.log(data));
Или внутри другой async-функции:
async function handleData() {
const data = await fetchData();
console.log(data);
}
Как работает await
Ключевое слово await приостанавливает выполнение только внутри текущей async-функции, пока промис не завершится. При этом основной поток выполнения не блокируется — другие задачи продолжают работать.
async function example() {
console.log('Начало');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('Прошла секунда');
}
Вывод:
Начало
(через 1 секунду) Прошла секунда
Обработка ошибок
Ошибки в async/await обрабатываются с помощью стандартного try/catch:
async function safeFetch() {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) throw new Error('Сервер вернул ошибку');
const data = await response.json();
return data;
} catch (error) {
console.error('Не удалось загрузить данные:', error.message);
throw error; // можно пробросить дальше, если нужно
}
}
Это гораздо удобнее, чем .catch() в цепочках промисов, особенно при сложной логике.
Важные ограничения
awaitможно использовать только внутри функций, объявленных какasync- Нельзя использовать
awaitна верхнем уровне модуля (вне функции), если только не используется top-level await (поддержка зависит от окружения; в React Native — не рекомендуется) async-функция всегда возвращает промис, даже если в ней нетawait
Пример: последовательная и параллельная загрузка
Последовательно (медленно):
async function loadSequentially() {
const user = await fetchUser();
const posts = await fetchPosts(user.id);
return { user, posts };
}
Параллельно (быстро):
async function loadInParallel() {
const userPromise = fetchUser();
const postsPromise = fetchPosts(); // предположим, что ID не нужен сразу
const user = await userPromise;
const posts = await postsPromise;
return { user, posts };
}
Или с Promise.all:
async function loadWithAll() {
const [user, posts] = await Promise.all([fetchUser(), fetchPosts()]);
return { user, posts };
}
Рекомендация
Используйте async/await в большинстве случаев — он проще, читаемее и лучше сочетается с обычными конструкциями языка (if, for, try/catch). Избегайте смешивания .then() и await в одном блоке кода без веской причины.