Вернуться к уроку

Finally или просто код?

важность: 5

Сравните два фрагмента кода.

  1. Первый использует finally для выполнения кода по выходу из try..catch:

    try {
      начать работу
      работать
    } catch (e) {
      обработать ошибку
    } finally {
      финализация: завершить работу
    }
  2. Второй фрагмент просто ставит очистку ресурсов за try..catch:

    try {
      начать работу
    } catch (e) {
      обработать ошибку
    }
    
    финализация: завершить работу

Нужно, чтобы код финализации всегда выполнялся при выходе из блока try..catch и, таким образом, заканчивал начатую работу. Имеет ли здесь finally какое-то преимущество или оба фрагмента работают одинаково?

Если имеет, то дайте пример когда код с finally работает верно, а без – неверно.

Разница в поведении станет очевидной, если рассмотреть код внутри функции.

Поведение будет различным, если управление каким-то образом выпрыгнет из try..catch.

Например, finally сработает после return, но до передачи управления внешнему коду:

function f() {
  try {
    ...
    return result;
  } catch (e) {
    ...
  } finally {
    очистить ресурсы
  }
}

Или же управление может выпрыгнуть из-за throw:

function f() {
  try {
    ...

  } catch (e) {
    ...
    if(не умею обрабатывать эту ошибку) {
      throw e;
    }

  } finally {
    очистить ресурсы
  }
}

В этих случаях именно finally гарантирует выполнение кода до окончания работы f, просто код не будет вызван.