JavaScriptの例外処理
試して…捕まえて…ついに
例外をキャッチして処理します。ネストがサポートされています。
function test(){
try {
// throw true;
throw 9527;
// throw '我是一个字符串';
// throw new Error('一个异常');
}
catch (e) {
if(typeof e === 'boolean'){
console.error("catch 到 boolean:", e);
}
if(typeof e === 'number'){
console.error("catch 到 number:", e);
}
if(typeof e === 'string'){
console.error("catch 到 string:", e);
}
if (e instanceof Error) {
console.error("catch 到:", e.message);
}
}
finally {
console.log("finally 块始终触发");
}
}
投げる
- throw は基本型を直接スローすることも、オブジェクトをスローすることもできます。
- 必要に応じて、例外タイプをカスタマイズできます。また、デフォルトの JS によっていくつかの例外が提供されます。
非同期での例外
- 同期コードは、
try catch
非同期メソッドでスローされた例外をキャッチできません。含むPromise.reject
。
try{
Promise.reject('失败');
}catch(err){
console.error(`try catch 捕获:${
err}`);
}
// Promise {<rejected>: '失败'}
// Uncaught (in promise) 失败
try{
Promise.resolve('成功').then(data => {
throw new Error(`你${
data}个鸡儿!`);});
}catch(err){
console.error(`try catch 捕获:${
err}`);
}
// Promise {<rejected>: Error: 你成功个鸡儿!
// Uncaught (in promise) Error: 你成功个鸡儿!
- 非同期例外は
.catch
チェーンで捕捉する必要があります。then(undefined, 拒绝(data))
の略称です。
try{
Promise.reject('失败').catch(err=>console.log(`异步的.catch 捕获:${
err}`));
}catch(err){
console.error(`try catch 捕获:${
err}`);
}
// 异步的.catch 捕获:失败
try{
Promise.resolve('成功')
.then(data => {
throw new Error(`你${
data}个鸡儿!`);})
.catch(err=>console.log(`异步的.catch 捕获:${
err}`));
}catch(err){
console.error(`try catch 捕获:${
err}`);
}
// 异步的.catch 捕获:Error: 你成功个鸡儿!
async...await
連携を使用しPromise
て同期実行に変換し、try catch
キャプチャを実現できます。ただし、連鎖していないことが前提です.catch
。
try{
await Promise.reject('失败');
}catch(err){
console.error(`try catch 捕获:${
err}`);
}
// try catch 捕获:失败
try{
await Promise.resolve('成功')
.then(data => {
throw new Error(`你${
data}个鸡儿!`);});
}catch(err){
console.error(`try catch 捕获:${
err}`);
}
// try catch 捕获:Error: 你成功个鸡儿!
次のものは.catch
切り詰められています。
try{
await Promise.reject('失败').catch(err=>console.log(`异步的.catch 捕获:${
err}`));
}catch(err){
console.error(`try catch 捕获:${
err}`);
}
// 异步的.catch 捕获:失败
もちろん.catch
途中で投げ続けることも可能です。try catch
このようにして、再び外部を取り込むことができます。
try{
await Promise.reject('失败')
.catch(err=>{
console.log(`异步的.catch 捕获:${
err}`);
throw '异步 .catch 继续抛的异常';
});
}catch(err){
console.error(`try catch 捕获:${
err}`);
}
// 异步的.catch 捕获:失败
// try catch 捕获:异步 .catch 继续抛的异常
とはいえ、別のリンクがあると.catch
また切れてしまいます。。。
try{
await Promise.reject('失败')
.catch(err=>{
console.log(`异步的.catch 捕获:${
err}`);
throw '异步 .catch 继续抛的异常';
})
.catch(err=>{
console.log(`第二个异步.catch 截胡:${
err}`);
});
}catch(err){
console.error(`try catch 捕获:${
err}`);
}
// 异步的.catch 捕获:失败
// 第二个异步.catch 截胡:异步 .catch 继续抛的异常
then および catch 関数がネストされて呼び出されるとき
- 複数の関数のネストされた呼び出しによって形成されるチェーン
Promise
。
これをチェーンとして見ることができ、then と catch のどちらを使用するかというロジックが明確になります。(私の脳は、サブ関数が呼び出される場所に含まれる then と catch を埋めます) - 基本的にチェーンなので前方でのキャッチの優先度は高い。それを引き継いでキャッチするか、その後続行させるかは、ビジネス ニーズによって異なります。
function main() {
return Promise.resolve('成功')
.then(data => {
console.log(`1、main 中的第一个 then:${
data}`); // 1 执行
return subFun(data);
})
.then(data => {
console.log(`4、main 中的第二个 then:${
data}`); // 4 执行
return data;
})
.catch(err=>{
// 4.5 跳过
console.log(`main 中的.catch 捕获到:${
err}`) // 此时状态 resolve 这个 catch 被跳过。
return err;
});
}
function subFun(data){
return Promise.resolve('data')
.then(data => {
console.log(`2、subFun 中的第一个 then:${
data}`); // 2 执行
throw `subFun 中抛异常`; // 抛异常,从此走上 reject 之路
})
.then(data => {
// 2.5 跳过
console.log(`subFun 中的第二个 then:${
data}`); // 此时状态 reject 这个 then 被跳过。
return data;
})
.catch(err=>{
console.log(`3、subFun 中的.catch 捕获:${
err}`) // 3 执行
return err; // 捕获异常,回归 resolve 之路
});
}
main()
.then(data => console.log(`5、最后的then:${
data}`) ) // 5 执行
.catch(err => console.error(`最后的catch :${
err}`) ); // 5.5 跳过
1、main 中的第一个 then:成功
2、subFun 中的第一个 then:data
3、subFun 中的.catch 捕获:subFun 中抛异常
4、main 中的第二个 then:subFun 中抛异常
5、最后的then:subFun 中抛异常