Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Блок finally». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`finally` це блок, який виконується завжди після `try` і `catch`, незалежно від результату: чи все пройшло успішно, чи виникла помилка, чи спрацював `throw`, чи з функції вже зроблено `return`.** Саме тому його використовують для завершальних дій, які не можна пропустити: закрити з'єднання, зупинити таймер, зняти блокування, прибрати індикатор завантаження. ```javascript try { openConnection(); runQuery(); } catch (error) { console.error("Error:", error); } finally { closeConnection(); // виконається в будь-якому разі } ``` **Ключове:** `finally` гарантує прибирання ресурсів, але `return` усередині нього перезаписує результат з `try` чи `catch` і навіть «гасить» кинуту помилку, тому так робити не варто.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**Блок `finally` у конструкції `try...catch...finally` це частина механізму обробки помилок, яка виконує код у будь-якому разі, незалежно від того, сталася помилка чи ні.** Він завершує роботу конструкції: спочатку `try`, потім за потреби `catch`, і останнім завжди `finally`. ## Теорія ### TL;DR - `finally` виконується завжди, після `try` і після `catch`. - Він спрацює і тоді, коли в `try` була помилка, і тоді, коли її не було. - Він спрацює навіть якщо з функції вже зроблено `return` з блоку `try` або `catch`. - Він спрацює навіть якщо помилка виникла всередині самого `catch`. - Типове застосування: звільнення ресурсів і прибирання стану. - `return` усередині `finally` перезаписує результат функції, це погана практика. ### Швидкий приклад ```javascript try { // код, який може викликати помилку } catch (error) { // обробка помилки } finally { // код, який виконається в будь-якому разі } ``` ### Як працює покроково 1. Виконується код у блоці `try`. 2. Якщо в `try` помилки немає, `catch` пропускається, виконується `finally`. 3. Якщо в `try` виникла помилка, виконується `catch`, а потім `finally`. 4. Після `finally` програма продовжує виконання далі. Приклад 1. Помилки немає, `finally` все одно виконується: ```javascript try { console.log("try: усе добре"); } catch (e) { console.log("catch: помилка"); } finally { console.log("finally: виконується завжди"); } ``` Вивід: ```text try: усе добре finally: виконується завжди ``` Приклад 2. Помилка є, `finally` теж виконується: ```javascript try { throw new Error("Помилка!"); } catch (e) { console.log("catch:", e.message); } finally { console.log("finally: виконується завжди"); } ``` Вивід: ```text catch: Помилка! finally: виконується завжди ``` ### finally і return Навіть якщо з блоку `try` зроблено `return`, блок `finally` усе одно виконується перед виходом з функції: ```javascript function test() { try { console.log("try"); return "З try"; } catch { console.log("catch"); } finally { console.log("finally"); } } console.log("Результат:", test()); ``` Вивід: ```text try finally Результат: З try ``` Але якщо `return` є в самому `finally`, він перезаписує результат з `try` або `catch`: ```javascript function test() { try { return "З try"; } finally { return "З finally"; } } console.log(test()); // "З finally" ``` Це вважається поганою практикою, бо робить поведінку функції непередбачуваною: значення з `try` мовчки зникає. ### finally при помилці в catch `finally` відпрацює, навіть якщо в `catch` виникла нова помилка. Спочатку виконається прибирання, і лише потім помилка полетить далі вгору по стеку: ```javascript try { throw new Error("Помилка в try"); } catch (e) { console.log("catch:", e.message); throw new Error("Помилка в catch"); } finally { console.log("finally все одно виконається"); } ``` Вивід: ```text catch: Помилка в try finally все одно виконається Uncaught Error: Помилка в catch ``` Так само працює конструкція `try...finally` зовсім без `catch`: помилка не перехоплюється, але прибирання гарантовано відбувається перед тим, як вона піде далі. ### Основні застосування Звільнення ресурсів: ```javascript 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` бізнес-логіку.** Це блок завершення, а не продовження сценарію, і читати таку функцію стає важко.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.