← Назад к вопросам
В чем разница между async/await и finally?
1.8 Middle🔥 241 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
В чем разница между async/await и finally
Введение
async/await и finally — это разные концепции в JavaScript:
- async/await — синтаксис для работы с промисами (асинхронным кодом)
- finally — блок в try/catch, который выполняется всегда
Они решают разные задачи, но часто используются вместе.
1. async/await — синтаксис для асинхронного кода
async — ключевое слово, которое превращает функцию в асинхронную и позволяет использовать await:
// Без async/await (Promises)
function fetchUser() {
return fetch('/api/user')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
}
// С async/await
async function fetchUser() {
try {
const response = await fetch('/api/user');
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}
await — ключевое слово, которое ждет выполнения промиса:
async function processData() {
// await ждет, пока промис разрешится
const user = await fetch('/api/user').then(r => r.json());
const posts = await fetch(`/api/user/${user.id}/posts`).then(r => r.json());
return { user, posts };
}
2. finally — блок, который выполняется всегда
finally — часть конструкции try/catch/finally, которая выполняется независимо от результата:
// Без finally
try {
const data = JSON.parse(jsonString);
console.log(data);
} catch (error) {
console.error('Parse error:', error);
}
console.log('Done'); // Выполнится всегда
// С finally
try {
const data = JSON.parse(jsonString);
console.log(data);
} catch (error) {
console.error('Parse error:', error);
} finally {
console.log('Done'); // Гарантированно выполнится
}
3. Разница: структура и назначение
| Аспект | async/await | finally |
|---|---|---|
| Тип | Синтаксис для асинхронного кода | Блок обработки исключений |
| Назначение | Упрощение работы с промисами | Очистка ресурсов |
| Использование | В функциях | В try/catch |
| Выполнение | Последовательное | Всегда (успех или ошибка) |
| Аналог | Promises с .then/.catch | finally для синхронного кода |
4. async/await: примеры
// Простой пример
async function greet() {
return 'Hello';
}
const result = greet(); // Возвращает Promise
await greet(); // 'Hello'
// Множественные await
async function getUserData(userId) {
const user = await fetch(`/api/users/${userId}`).then(r => r.json());
const comments = await fetch(`/api/users/${userId}/comments`).then(r => r.json());
const posts = await fetch(`/api/users/${userId}/posts`).then(r => r.json());
return { user, comments, posts };
}
// Параллельное выполнение
async function getMultipleUsers(ids) {
const users = await Promise.all(
ids.map(id => fetch(`/api/users/${id}`).then(r => r.json()))
);
return users;
}
5. finally: примеры
// finally в синхронном коде
try {
const data = JSON.parse(jsonString);
} catch (error) {
console.error('Error:', error);
} finally {
console.log('Parsing attempt finished');
}
// finally в асинхронном коде
async function fetchData() {
let data;
try {
data = await fetch('/api/data').then(r => r.json());
} catch (error) {
console.error('Fetch failed:', error);
} finally {
console.log('Fetch attempt finished');
}
return data;
}
6. Использование вместе: try/catch/finally с async/await
async function processFile(filename) {
let file;
try {
// 1. Загружаем файл (async)
const response = await fetch(`/files/${filename}`);
if (!response.ok) throw new Error('File not found');
file = await response.json();
console.log('File loaded:', file);
} catch (error) {
// 2. Обработка ошибок
console.error('Error:', error.message);
} finally {
// 3. Очистка (выполнится всегда)
console.log('Processing finished');
}
}
7. Практический пример: управление ресурсами
// Пример с finally для очистки ресурсов
async function fetchUserData(userId) {
let connection;
try {
// Создаем соединение
connection = await openDatabase();
// Запрашиваем данные
const user = await connection.query('SELECT * FROM users WHERE id = ?', [userId]);
console.log('User data:', user);
return user;
} catch (error) {
console.error('Database error:', error);
throw error; // Пробрасываем ошибку дальше
} finally {
// Очищаем соединение (выполнится даже при ошибке)
if (connection) {
await connection.close();
console.log('Connection closed');
}
}
}
8. finally гарантирует выполнение кода
Это особенно важно для очистки ресурсов:
async function downloadFile() {
const startTime = Date.now();
try {
// Загружаем файл
const file = await fetch('/file.zip').then(r => r.blob());
saveFile(file);
console.log('File saved');
return file;
} catch (error) {
console.error('Download failed:', error);
throw error;
} finally {
// Логируем время выполнения (выполнится всегда)
const elapsed = Date.now() - startTime;
console.log(`Operation took ${elapsed}ms`);
// Закрываем UI элементы (прогресс бар и т.д.)
closeProgressBar();
}
}
// Результат:
// 1. Попытка загрузить файл
// 2. При успехе: "File saved" + "Operation took XXXms"
// 3. При ошибке: "Download failed" + "Operation took XXXms"
// 4. finally всегда выполнится и закроет прогресс бар
9. Сравнение: Promises vs async/await
// С Promises и .finally()
fetch('/api/data')
.then(r => r.json())
.then(data => console.log(data))
.catch(error => console.error(error))
.finally(() => console.log('Done'));
// С async/await и finally
async function getData() {
try {
const r = await fetch('/api/data');
const data = await r.json();
console.log(data);
} catch (error) {
console.error(error);
} finally {
console.log('Done');
}
}
// Обе версии имеют одинаковый результат, но async/await более читаемый
10. Частые ошибки
// ❌ Неправильно: finally не заменяет catch
async function badExample() {
try {
const data = await fetch('/api/data').then(r => r.json());
console.log(data);
} finally {
// Ошибка будет залогирована, но не обработана
console.log('Done');
}
}
// ✅ Правильно: используй catch для обработки ошибок
async function goodExample() {
try {
const data = await fetch('/api/data').then(r => r.json());
console.log(data);
} catch (error) {
console.error('Error:', error);
} finally {
console.log('Done');
}
}
// ❌ Неправильно: await вне async функции
function badAsync() {
await fetch('/api/data'); // SyntaxError
}
// ✅ Правильно: await только в async функциях
async function goodAsync() {
await fetch('/api/data');
}
Заключение
- async/await — это синтаксис для упрощенной работы с асинхронным кодом (промисами)
- finally — это блок, который выполняется всегда, независимо от успеха или ошибки
- Они решают разные проблемы и часто используются вместе: async/await для асинхронного кода, finally для гарантированной очистки ресурсов