Подтвердить что ты не робот

Javascript try... catch... else... наконец, как Python, Java, Ruby и т.д.

Как Javascript может дублировать четырехуровневую модель исполнения try - catch - else - finally, поддерживаемую другими языками?

Ясное краткое резюме из Python 2.5, что нового. В условиях Javascript:

// XXX THIS EXAMPLE IS A SYNTAX ERROR
try {
  // Protected-block
} catch(e) {
  // Handler-block
} else {
  // Else-block
} finally {
  // Final-block
}

Выполняется код в Защищенном блоке. Если код генерирует исключение, выполняется Обработчик-блок; Если исключение не выбрано, выполняется Else-block.

Независимо от того, что произошло ранее, Final-block выполняется, как только блок кода завершен, и обрабатываются любые обработанные исключения. Даже если возникает ошибка в Обработчике-блоке или Else-block и возникает новое исключение, код в Конечный блок все еще запущен.

Обратите внимание, что сокращение Else-block и вставка в конце Защищенного блока неверно. Если ошибка произошла в Else-block, ее нельзя обрабатывать Обработчик-блок.

4b9b3361

Ответ 1

Немного расширяя идею jhs, вся концепция может быть помещена внутри функции, чтобы обеспечить еще большую читаемость:

var try_catch_else_finally = function(protected_code, handler_code, else_code, finally_code) {
  try {
    var success = true;
    try {
      protected_code();
    } catch(e) {
      success = false;
      handler_code({"exception_was": e});
    }
    if(success) {
      else_code();
    }
  } finally {
    finally_code();
  }
};

Затем мы можем использовать его так (очень похоже на путь python):

try_catch_else_finally(function() {
  // protected block
}, function() {
  // handler block
}, function() {
  // else block
}, function() {
  // final-block
});

Ответ 2

Я знаю, что это старое, но вот чисто синтаксическое решение, которое я считаю правильным:

try {
    // Protected-block
    try {
        // Else-block
    } catch (e) {
        // Else-handler-block
    }
} catch(e) {
    // Handler-block
} finally {
    // Final-block
}

Код в Защищенном блоке выполняется. Если код выдает ошибку, выполняется блок обработчика; Если ошибка не выдана, Else-block выполняется.

Независимо от того, что произошло ранее, Final-block выполняется после завершения блока кода и обработки любых сгенерированных ошибок. Даже если есть ошибка в блоке обработчика или блоке Else, код в блоке Final все еще выполняется.

Если в блоке Else выдается ошибка, она обрабатывается не блоком Handler, а блоком Else-handler

А если знаешь, что Else-блок не кинет

try {
    // Protected-block
    // Else-block
} catch(e) {
    // Handler-block
} finally {
    // Final-block
}

Мораль истории, не бойся отступать;)

Примечание: это работает, только если блок Else-handler- никогда не выбрасывает.

Ответ 3

Javascript не имеет синтаксиса для поддержки сценария без исключения. Лучшим обходным решением является вложенный оператор try, похожий на "устаревший" метод из PEP 341

// A pretty-good try/catch/else/finally implementation.
try {
  var success = true;
  try {
    protected_code();
  } catch(e) {
    success = false;
    handler_code({"exception_was": e});
  }
  if(success) {
    else_code();
  }
} finally {
  this_always_runs();
}

Помимо читаемости, единственной проблемой является переменная success. Если protected_code устанавливает window.success = false, это не сработает. Менее читаемый, но безопасный способ использует пространство имен функций:

// A try/catch/else/finally implementation without changing variable bindings.
try {
  (function() {
    var success = true;
    try {
      protected_code();
    } catch(e) {
      success = false;
      handler_code({"exception_was": e});
    }
    if(success) {
      else_code();
    }
  })();
} finally {
  this_always_runs();
}

Ответ 4

Я знаю, что вопрос старый, и ответы уже даны, но я думаю, что мой ответ является самым простым, чтобы получить "else" в блоке try-catch javascripts.

var error = null;
try {
    /*Protected-block*/
} catch ( catchedError ) {
    error = catchedError; //necessary to make it available in finally-block
} finally {
    if ( error ) {
        /*Handler-block*/
        /*e.g. console.log( 'error: ' + error.message );*/
    } else {
        /*Else-block*/
    }
    /*Final-block*/
}

Ответ 5

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

try { 
    //do block 
    cb(null, result);
} catch(err) {
    // err report
    cb(err)
}

Но ошибка в успехе cb вызывает проблему вызова cb во второй раз. Поэтому вместо этого я начал использовать

try { 
    //do block 
    try { 
        cb(null, result); 
    } catch(err) { 
        // report uncaught error 
    }
} catch(err) {
    // err report
    cb(err)
}

который является вариантом решения @cbarrick.