node.js 實(shí)戰(zhàn):如何優(yōu)雅的處理異常

概述


在使用異步的終極解決方案-ES7的async/await同時,如何優(yōu)雅的處理錯誤提高代碼的兼容性讓作為碼農(nóng)的我很頭疼。在項(xiàng)目實(shí)戰(zhàn)中合理的使用try...catch...讓代碼的兼容和穩(wěn)定性大大增強(qiáng)。

本文將對 try...catch... 從為什么要用->到如何使用->實(shí)戰(zhàn)三個方面來敘述。

1、為什么要用 try...catch...


async function funcAsync(){
   console.log('\n---begin---\n');
   await ih_func();
   console.log('------end-----');
}

function ih_func(){
  return new Promise(function (resolve, reject) {
    //這里相當(dāng)于throw一個異常了
    reject('error');
  });
}

funcAsync();
運(yùn)行結(jié)果

你一定會好奇為什么只打印了begin而沒有打印end,這是因?yàn)閞eject('error'); 相當(dāng)于throw一個異常了,所以程序就不會繼續(xù)往下執(zhí)行了,想要程序繼續(xù)執(zhí)行下去就需要處理throw出來的異常。

2、如何使用 try...catch... 處理異常

async function funcAsync(){
   console.log('\n---begin---\n');
   try{
     await ih_func();
   } catch(e){
     console.log(e);
   }
   console.log('------end-----');
}

function ih_func(){
  return new Promise(function (resolve, reject) {
    //這里相當(dāng)于throw一個異常了
    reject('error');
  });
}

funcAsync();
運(yùn)行結(jié)果

驚奇的發(fā)現(xiàn)通過 try...catch... 處理異常后的程序神奇的執(zhí)行完成了。

在try{}中的代碼 throw 出來的異常會被 catch 捕獲到,程序認(rèn)為你處理異常了,所以繼續(xù)往下執(zhí)行了

2、 try...catch... 之實(shí)戰(zhàn)

  • 程序如何處理異常

async function funcAsync(){
  for(let i=0; i<3; i++){
    try{  
      console.log('\n---begin---\n');
      await ih_func();
      console.log('------end-----');
    } catch(e){
      console.log(e);
    }
    console.log('-----end2-----');
  }
}

function ih_func(){
  return new Promise(function (resolve, reject) {
    //這里相當(dāng)于throw一個異常了
    reject('error');
  });
}

funcAsync();
運(yùn)行結(jié)果

上面代碼運(yùn)行代碼后發(fā)現(xiàn),當(dāng) ih_func() throw出異常后,被外層的catch捕獲并處理,而且直接跳出打印end2。并沒有我們預(yù)期中,繼續(xù)往下執(zhí)行打印end。

  • 多層try...catch... 如何處理異常

async function funcAsync_1(){
   try{  
     await funcAsync_2();
   } catch(e){
     console.log('funcAsync_1');
     console.log(e);
   }
   console.log('funcAsync_1 ----  end');
}

async function funcAsync_2(){
  for(let i=0; i<3; i++){
    console.log('\n---begin'+ i +'---\n');
    try{  
      await ih_func(i);
    } catch(e){
      console.log(e);
    }
    console.log('------end'+ i +'-----');
  }
}

function ih_func(args){
  return new Promise(function (resolve, reject) {
    //這里相當(dāng)于throw一個異常了
    reject('error' + args);
  });
}

funcAsync_1();
運(yùn)行結(jié)果
  • 結(jié)論

一層 try...catch...的時候: 當(dāng)程序 throw 出異常后,被外層的catch捕獲并處理,程序在catch捕獲處繼續(xù)執(zhí)行下去。

多層try...catch...的時候:當(dāng)程序 throw 出異常后,會被離異常最近的catch捕獲并處理,程序在catch捕獲處繼續(xù)執(zhí)行下去。

當(dāng)程序throw出一個異常后,會從里往外一直尋找處理異常的catch,當(dāng)找到離異常最近的catch時,會被這個catch處理,并不會再往外傳遞異常,而且會在catch處理當(dāng)前代碼行繼續(xù)往下執(zhí)行。

  • 如何提高程序的健壯性

async function funcAsync(){
  for(let i=0; i<3; i++){
    console.log('\n---begin'+ i +'---\n');
    try{  
      await ih_func(i);
    } catch(e){
      console.log(e);
    }
    console.log('------end'+ i +'-----');
  }
}

function ih_func(args){
  return new Promise(function (resolve, reject) {
    //這里相當(dāng)于throw一個異常了
    reject('error' + args);
  });
}

funcAsync();
運(yùn)行結(jié)果

對于多個await Promise返回值的時候,可以對具有Promise返回值為reject的異步操作時,使用 try...catch...不僅可以增強(qiáng)代碼的健壯性,而且使代碼在我們預(yù)期中執(zhí)行下去。

示例代碼

https://github.com/yangxiaopingios/koaExample/blob/master/code/script/twoExample.js

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容