Книга: Выразительный JavaScript

Подчищаем за исключениями

Подчищаем за исключениями

Представьте следующую ситуацию: функция withContext желает удостовериться, что во время её выполнения переменная верхнего уровня context содержит специальное значение контекста. В конце выполнения функция восстанавливает прежнее значение переменной.

var context = null;
function withContext(newContext, body) {
  var oldContext = context;
  context = newContext;
  var result = body();
  context = oldContext;
  return result;
}

Что, если функция body выбросит исключение? В таком случае вызов withContext будет выброшен исключением из стека, и переменной context никогда не будет возвращено первоначальное значение.

Но у инструкции try есть ещё одна особенность. За ней может следовать блок finally, либо вместо catch, либо вместе с catch. Блок finally означает «выполнить код в любом случае после выполнения блока try». Если функции надо что-то подчистить, то подчищающий код нужно включать в блок finally.

function withContext(newContext, body) {
  var oldContext = context;
  context = newContext;
  try {
    return body();
  } finally {
    context = oldContext;
  }
}

Заметьте, что нам больше не нужно сохранять результат вызова body в отдельной переменной, чтобы вернуть его. Даже если мы возвращаемся из блока try, блок finally всё равно будет выполнен. Теперь мы можем безопасно сделать так:

try {
  withContext(5, function() {
    if (context < 10)
      throw new Error("Контекст слишком мал!");
  });
} catch (e) {
  console.log("Игнорируем: " + e);
}
// ? Игнорируем: Error: Контекст слишком мал!
console.log(context);
// ? null

Несмотря на то, что вызываемая из withContext функция «сломалась», сам по себе withContext по-прежнему подчищает значение переменной context.

Оглавление книги


Генерация: 1.918. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз