Javascript try…catch…else…finally like Python, Java, Ruby, etc

戏子无情 提交于 2020-01-09 09:21:25

问题


How can Javascript duplicate the four-part try-catch-else-finally execution model that other languages support?

A clear, brief summary is from the Python 2.5 what's new. In Javascript terms:

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

The code in Protected-block is executed. If the code throws an exception, Handler-block is executed; If no exception is thrown, Else-block is executed.

No matter what happened previously, Final-block is executed once the code block is complete and any thrown exceptions handled. Even if there’s an error in Handler-block or Else-block and a new exception is raised, the code in Final-block is still run.

Note that cutting Else-block and pasting at the end of Protected-block is wrong. If an error happens in Else-block, it must not be handled by Handler-block.


回答1:


Extending the idea of jhs a little, the whole concept could be put inside a function, to provide even more readability:

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

Then we can use it like this (very similar to the python way):

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



回答2:


I know this is old, but here is a pure syntax solution, which I think is the proper way to go:

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

The code in Protected-block is executed. If the code throws an error, Handler-block is executed; If no error is thrown, Else-block is executed.

No matter what happened previously, Final-block is executed once the code block is complete and any thrown errors handled. Even if there’s an error in Handler-block or Else-block, the code in Final-block is still run.

If an error is thrown in the Else-block it is not handled by the Handler-block but instead by the Else-handler-block

And if you know that the Else-block will not throw:

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

Moral of the story, don't be afraid to indent ;)

Note: this works only if the Else-handler-block never throws.




回答3:


Javascript does not have the syntax to support the no-exception scenario. The best workaround is nested try statements, similar to the "legacy" technique from 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();
}

Besides readability, the only problem is the success variable. If protected_code sets window.success = false, this will not work. A less readable but safer way uses a function namespace:

// 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:


I know the question is old and answers has already given but I think that my answer is the simplest to get an "else" in 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*/
}



回答5:


Here's another solution if the problem is the common one of not wanting the error callback to be called if there is an uncaught error thrown by the first callback. ... i.e. conceptually you want ...

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

But an error in the success cb causes the problem of cb getting called a second time. So instead I've started using

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

which is a variant on @cbarrick's solution.



来源:https://stackoverflow.com/questions/4872170/javascript-try-catch-else-finally-like-python-java-ruby-etc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!