Javascript尝试... catch ... else ...最后像Python,Java,Ruby等

时间:2011-02-02 08:23:25

标签: javascript try-catch

Javascript如何复制其他语言支持的四部分try - catch - else - finally执行模型?

简明扼要的摘要来自Python 2.5 what's new。在Javascript术语中:

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

执行受保护区块中的代码。如果代码抛出异常,则执行 Handler-block ;如果没有抛出异常,则执行 Else-block

无论以前发生了什么,一旦代码块完成并处理了任何抛出的异常,就会执行 Final-block 。即使处理程序块 Else-block 出现错误并引发新的异常, Final-block 中的代码仍会运行

请注意,在受保护的块的末尾剪切 Else-block 并粘贴错误。如果 Else-block 中发生错误,则处理程序块

5 个答案:

答案 0 :(得分:31)

我知道这是旧的,但这是一个纯语法解决方案,我认为这是正确的方法:

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

执行受保护区块中的代码。如果代码抛出错误,则执行处理程序块;如果没有抛出错误,则执行 Else-block

无论以前发生了什么,一旦代码块完成并处理了任何抛出的错误,就会执行 Final-block 。即使处理程序块 Else-block 出错, Final-block 中的代码仍会运行。

如果 Else-block 中出现错误,处理程序块处理 ,而是由处理其他处理程序块

如果你知道 Else-block 不会抛出:

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

故事的道德,不要害怕缩进;)

注意:仅当 Else-handler-block 永不抛出时才有效。

答案 1 :(得分:24)

稍微扩展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 :(得分:8)

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();
}

答案 3 :(得分:6)

我知道这个问题已经过时了,已经给出了答案,但我认为我的答案是最简单的,而其他的#34;在javascripts中try-catch-block。

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*/
}

答案 4 :(得分:0)

如果问题很常见,这是另一种解决方案,如果第一个回调引发未捕获的错误,则不希望调用错误回调。 ...即从概念上讲您想要...

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解决方案的一种变体。