Finally или просто код?
Сравните два фрагмента кода.
-
Первый использует
finally
для выполнения кода послеtry..catch
:try { начать работу работать } catch (e) { обработать ошибку } finally { очистить рабочее пространство }
-
Второй фрагмент просто ставит очистку после
try..catch
:try { начать работу работать } catch (e) { обработать ошибку } очистить рабочее пространство
Нам определённо нужна очистка после работы, неважно возникли ошибки или нет.
Есть ли здесь преимущество в использовании finally
или оба фрагмента кода одинаковы? Если такое преимущество есть, то дайте пример, когда оно проявляется.
Разница в поведении станет очевидной, если рассмотреть код внутри функции.
Поведение будет различным, если управление каким-то образом выпрыгнет из try..catch
.
Например, когда есть return
внутри try..catch
. Секция finally
работает в любом случае при любом выходе из try..catch
, даже через return
: сразу после того как try..catch
выполнится, но до того, как вызывающий код получит контроль.
function f() {
try {
alert('начало');
return "result";
} catch (e) {
/// ...
} finally {
alert('очистка!');
}
}
f(); // очистка!
…Или когда есть throw
, например, как здесь:
function f() {
try {
alert('начало');
throw new Error("ошибка");
} catch (e) {
// ...
if("не могу обработать ошибку") {
throw e;
}
} finally {
alert('очистка!')
}
}
f(); // очистка!
Именно finally
гарантирует очистку. Если мы просто поместим код в конце f
, то он не выполнится в описанных ситуациях.