Javascriptは、他の言語がサポートする4つの部分からなる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
}
Protected-blockのコードが実行されます。コードが例外をスローした場合、Handler-blockが実行されます。例外がスローされない場合、Else-blockが実行されます。
以前に何が起こったとしても、コードブロックが完了し、スローされた例外が処理されると、Final-blockが実行されます。 Handler-blockまたはElse-blockにエラーがあり、新しい例外が発生した場合でも、Final-blockのコードは実行されます。 。
Else-blockを切り取ってProtected-blockの最後に貼り付けるのは間違っていることに注意してください。 Else-blockでエラーが発生した場合、はHandler-blockで処理してはなりません。
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
});
私はこれが古いことを知っていますが、ここに純粋な構文ソリューションがあります。これが適切な方法だと思います。
try {
// Protected-block
try {
// Else-block
} catch (e) {
// Else-handler-block
}
} catch(e) {
// Handler-block
} finally {
// Final-block
}
Protected-blockのコードが実行されます。コードがエラーをスローした場合、Handler-blockが実行されます。エラーがスローされない場合、Else-blockが実行されます。
以前に何が起こったとしても、コードブロックが完了し、スローされたエラーが処理されると、Final-blockが実行されます。 Handler-blockまたはElse-blockにエラーがあったとしても、Final-blockのコードは実行されます。
Else-blockでエラーがスローされた場合、Handler-blockによって処理されますnot =しかし代わりにElse-handler-block
そして、Else-blockがスローされないことがわかっている場合:
try {
// Protected-block
// Else-block
} catch(e) {
// Handler-block
} finally {
// Final-block
}
話の教訓、インデントすることを恐れないでください;)
注:これは、Else-handler-blockがスローされない場合にのみ機能します。
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();
}
私は質問が古く、答えがすでに与えられていることを知っていますが、私の答えはjavascriptstry-catch-blockで「else」を取得するのが最も簡単だと思います。
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*/
}
問題が、最初のコールバックによってスローされたキャッチされていないエラーがある場合にエラーコールバックが呼び出されたくないという一般的な問題である場合、別の解決策があります。 ...つまり、概念的には...
try {
//do block
cb(null, result);
} catch(err) {
// err report
cb(err)
}
しかし、成功したcbでエラーが発生すると、cbが2回呼び出されるという問題が発生します。だから代わりに私は使い始めました
try {
//do block
try {
cb(null, result);
} catch(err) {
// report uncaught error
}
} catch(err) {
// err report
cb(err)
}
これは@cbarrickのソリューションの変形です。