Блок finally
Блок finally у конструкції try...catch...finally це частина механізму обробки помилок, яка виконує код у будь-якому разі, незалежно від того, сталася помилка чи ні. Він завершує роботу конструкції: спочатку try, потім за потреби catch, і останнім завжди finally.
Теорія
TL;DR
finallyвиконується завжди, післяtryі післяcatch.- Він спрацює і тоді, коли в
tryбула помилка, і тоді, коли її не було. - Він спрацює навіть якщо з функції вже зроблено
returnз блокуtryабоcatch. - Він спрацює навіть якщо помилка виникла всередині самого
catch. - Типове застосування: звільнення ресурсів і прибирання стану.
returnусерединіfinallyперезаписує результат функції, це погана практика.
Швидкий приклад
try {
// код, який може викликати помилку
} catch (error) {
// обробка помилки
} finally {
// код, який виконається в будь-якому разі
}Як працює покроково
- Виконується код у блоці
try. - Якщо в
tryпомилки немає,catchпропускається, виконуєтьсяfinally. - Якщо в
tryвиникла помилка, виконуєтьсяcatch, а потімfinally. - Після
finallyпрограма продовжує виконання далі.
Приклад 1. Помилки немає, finally все одно виконується:
try {
console.log("try: усе добре");
} catch (e) {
console.log("catch: помилка");
} finally {
console.log("finally: виконується завжди");
}Вивід:
try: усе добре
finally: виконується завждиПриклад 2. Помилка є, finally теж виконується:
try {
throw new Error("Помилка!");
} catch (e) {
console.log("catch:", e.message);
} finally {
console.log("finally: виконується завжди");
}Вивід:
catch: Помилка!
finally: виконується завждиfinally і return
Навіть якщо з блоку try зроблено return, блок finally усе одно виконується перед виходом з функції:
function test() {
try {
console.log("try");
return "З try";
} catch {
console.log("catch");
} finally {
console.log("finally");
}
}
console.log("Результат:", test());Вивід:
try
finally
Результат: З tryАле якщо return є в самому finally, він перезаписує результат з try або catch:
function test() {
try {
return "З try";
} finally {
return "З finally";
}
}
console.log(test()); // "З finally"Це вважається поганою практикою, бо робить поведінку функції непередбачуваною: значення з try мовчки зникає.
finally при помилці в catch
finally відпрацює, навіть якщо в catch виникла нова помилка. Спочатку виконається прибирання, і лише потім помилка полетить далі вгору по стеку:
try {
throw new Error("Помилка в try");
} catch (e) {
console.log("catch:", e.message);
throw new Error("Помилка в catch");
} finally {
console.log("finally все одно виконається");
}Вивід:
catch: Помилка в try
finally все одно виконається
Uncaught Error: Помилка в catchТак само працює конструкція try...finally зовсім без catch: помилка не перехоплюється, але прибирання гарантовано відбувається перед тим, як вона піде далі.
Основні застосування
Звільнення ресурсів:
try {
openConnection();
runQuery();
} catch (e) {
console.error("Помилка:", e);
} finally {
closeConnection(); // виконується завжди
}Крім того, finally використовують, щоб:
- очистити тимчасові дані й кеші;
- зняти блокування або семафор;
- зупинити таймер чи скасувати підписку;
- прибрати індикатор завантаження в інтерфейсі незалежно від результату запиту;
- завершити операцію однаково як при успіху, так і при збої.
Підсумкова таблиця
| Блок | Коли виконується | Призначення |
|---|---|---|
try | Завжди | Код, де може статися помилка |
catch | Лише при помилці | Обробка винятків |
finally | Завжди | Прибирання, завершення, звільнення ресурсів |
Типові помилки
returnуfinally. Він перекриває значення зtryіcatch, а також може «проковтнути» кинуту помилку, тому функція починає брехати про свій результат.- Ставити в
finallyкод, який сам може впасти. Помилка в блоці прибирання перекриє початкову помилку, і справжню причину збою ви не побачите. - Вважати, що
finallyперехоплює помилку. Він не перехоплює: безcatchвиняток післяfinallyлетить далі вгору по стеку. - Дублювати прибирання і в
try, і вcatch, і вfinally. Достатньо одного місця, саме для цьогоfinallyй існує. - Класти в
finallyбізнес-логіку. Це блок завершення, а не продовження сценарію, і читати таку функцію стає важко.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.