1. 程式人生 > >前端JS 異常處理實踐

前端JS 異常處理實踐

機制 odi 可能 $.ajax time 返回 nal 需要 使用

前端異常處理,常見的場景是在“異步請求”的操作過程當中,所謂“異常”---就是“不正常”,程序的運行不符合我們的預期。

程序“正常”的處理,是我們在開發過程當中的“重中之重”,是必要的“硬性指標”。

而“異常處理”,很多時候可能連“指標”都沒有,更談不上什麽“硬性指標”了,所以,在開發當中是很容易被忽略的一個“主題”。

但是,“提高用戶體驗”與“提高程序可控性”又是兩個永恒的主題,“枝繁葉茂”就是我們追求的目標(枝---主功能;葉---細節;)。

在追求“枝繁葉茂”的過程當中,“異常處理”就是細節當中的重中之重,故此,對此進行了如下實踐:

常見的“異步請求”操作:1.ajax(以$.ajax為例);2.fetch;

此處對這兩種方式的“異常處理”進行了實踐(包括try,catch,finally,throw error,new Error(),console.error的運用),以fetch實踐為主,由於fetch返回的實際上是promise對象,為了方便查看測試效果,此處直接使用promise對象代替說明。

一.$.ajax相關

$.ajax({
   url: "/hello?name=平凡視界",
   type: "GET",
   success: (data) =>{
    //成功相關處理
    console.log(‘返回數據‘,data)
   },
   error: (err) 
=>{ //錯誤相關處理 404屬於該處理(經測試) //還可能是"timeout", "error", "notmodified" 和 "parsererror"。 console.log(‘錯誤處理‘,err); } });

二.fetch相關

實踐1:當程序運行遇到 throw error 時,JS引擎會停止後續業務執行,程序直接進入catch環節;

new Promise((res, rej) =>{
  console.log(‘異步開始。。。‘);
  setTimeout(() =>{
    const error = new Error(‘粗錯啦~‘);
    
throw error; //JS引擎會停止後續業務執行,程序直接進入catch環節 res(‘異步OK‘); },3000) }) .then((data) =>{ console.log(‘異步執行OK‘,data);//並沒有執行 },(data) =>{ console.log(‘異步執行拒絕‘,data);//並沒有執行 }) .then((data) =>{ console.log(‘二次then執行OK‘,data);//並沒有執行 }) .catch((err) =>{ console.error(‘嘿‘,err);//執行OK })

實踐2:當程序 resolve 時,在後續then操作當中註冊的resolve handle會順次執行,註冊的reject handle與catch並未執行;

new Promise((res, rej) =>{
  console.log(‘異步開始。。。‘);
  setTimeout(() =>{
    res(‘異步OK‘);
  },3000)
 })
 .then((data) =>{
  console.log(‘異步執行OK‘,data);//執行OK
 },(data) =>{
  console.log(‘異步執行拒絕‘,data);//並沒有執行
 })
 .then((data) =>{
  console.log(‘二次then執行OK‘,data);//執行OK
 })
 .catch((err) =>{
  console.error(‘嘿‘,err);//並沒有執行
 })

實踐3:當程序 reject 時,在後續“子1級”then操作當中註冊的reject handle執行---驗證1,其他註冊的resolve handle與catch並未執行;

new Promise((res, rej) =>{
  console.log(‘異步開始。。。‘);
  setTimeout(() =>{
    rej(‘異步失敗‘);
  },3000)
 })
 .then((data) =>{
  console.log(‘異步執行OK‘,data);//並沒有執行
 },(data) =>{
  console.log(‘異步執行拒絕‘,data);//執行OK
 })
 .then((data) =>{
  console.log(‘二次then執行OK‘,data);//執行OK
 })
 .catch((err) =>{
  console.error(‘嘿‘,err);//並沒有執行
 })

實踐4:當程序 reject 時,在後續“子2級”then操作當中註冊的reject handle執行---驗證2(子1級中,並沒有註冊reject handle相關的處理機制,故被在“子2級”then操作當中註冊的reject handle接收,並執行處理),其他註冊的resolve handle與catch並未執行;

new Promise((res, rej) =>{
  console.log(‘異步開始。。。‘);
  setTimeout(() =>{
    rej(‘異步失敗‘);
  },3000)
 })
 .then((data) =>{
  console.log(‘異步執行OK‘,data);//並沒有執行
 })
 .then((data) =>{
  console.log(‘二次then執行OK‘,data);//並沒有執行
 },(data) =>{
  console.log(‘二次then"接收"reject異步"執行結果"(拒絕)‘,data);//執行OK
 })
 .catch((err) =>{
  console.error(‘嘿‘,err);//並沒有執行
 })

實踐5:當程序 reject 時,在後續“子4級”then操作當中註冊的reject handle執行---驗證2(“子1級”至“子3級”中,並沒有註冊reject handle相關的處理機制,故被在“子4級”then操作當中註冊的reject handle接收,並執行處理),其他註冊的resolve handle與catch並未執行;

new Promise((res, rej) =>{
  console.log(‘異步開始。。。‘);
  setTimeout(() =>{
    rej(‘異步失敗‘);
  },3000)
 })
 .then((data) =>{
  console.log(‘異步執行OK1‘,data);//並沒有執行
 })
 .then((data) =>{
  console.log(‘異步執行OK2‘,data);//並沒有執行
 })
 .then((data) =>{
  console.log(‘異步執行OK3‘,data);//並沒有執行
 })
 .then((data) =>{
  console.log(‘二次then執行OK4‘,data);//並沒有執行
 },(data) =>{
  console.log(‘二次then"接收"reject異步"執行結果"(拒絕)‘,data);//執行OK
 })
 .catch((err) =>{
  console.error(‘嘿‘,err);//並沒有執行
 })

實踐6:當程序 reject 時,“子1級”至“子4級”中,並沒有註冊reject handle相關的處理機制,故被catch接收,並執行處理,其他註冊的resolve handle並未執行;

new Promise((res, rej) =>{
  console.log(‘異步開始。。。‘);
  setTimeout(() =>{
    rej(‘異步失敗‘);
  },3000)
 })
 .then((data) =>{
  console.log(‘異步執行OK1‘,data);//並沒有執行
 })
 .then((data) =>{
  console.log(‘異步執行OK2‘,data);//並沒有執行
 })
 .then((data) =>{
  console.log(‘異步執行OK3‘,data);//並沒有執行
 })
 .then((data) =>{
  console.log(‘異步執行OK4‘,data);//並沒有執行
 })
 .catch((err) =>{
  console.error(‘嘿‘,err);//執行OK-----rej的時候,“其後程序”沒有對rejct進行相應處理時,
  //catch會接收該reject響應,並進行處理
 })

三.try,catch,finally,throw error,new Error(),console.error的運用;

try{
  console.log("test");
  throw new Error(‘出錯了吧?‘);//throw 後面的參數,會被catch中的e接收
}
catch(e){
  // e == ‘出錯了吧?‘
  console.error(e);// 出錯了吧?
}
finally{
  console.log(‘怎麽都會執行‘);// 執行OK
}

四.總結

1.當程序執行遇到“throw error”時,JS引擎會停止後續業務執行,程序直接進入catch環節; (promise對象,try包裹的代碼塊) 2.promise: --- resolve: 大多時候(除:網絡故障與請求被阻止外),使用fetch()返回的 Promise被標記為resolve, 包括(接收到一個代表錯誤的 HTTP 狀態碼時,HTTP 響應的狀態碼是 404 或 500,但是,此時會將 resolve 的返回值的 ok 屬性設置為 false, 如果需要進行細分,可以根據該屬性進行細分---在“異步請求”中,處理的大多數異常或error針對該階段異常) --- reject: 使用fetch()返回的 Promise被標記為 reject的情況僅有兩種(1.網絡故障;2.請求被阻止(如“跨域”))
說明:當程序在reject時,如果後續沒有註冊“相關程序”來接收處理,那麽,該reject會被catch處理,在該reject發生之後註冊的一切reslove 業務將不會被執行; 當程序在reject時,如果後續有註冊“相關程序”來接收處理,那麽,該reject會被所“註冊”的函數進行處理,在該註冊函數之後的一切reslove 業務不會受該reject的影響,會依次執行,同時,catch不會被“該reject”觸發; 3.try catch finally:
try{
#1運行代碼
}
catch(err){
#1出錯,程序直接進入該環節
}
finally{
#1出錯 or 正常,程序都進入該環節
}

前端JS 異常處理實踐