91在线一级黄片|91视频在线观看18|成人夜间呦呦网站|91资源欧美日韩超碰|久久最新免费精品视频一区二区三区|国产探花视频在线观看|黄片真人免费三级片毛片|国产人无码视频在线|精品成人影视无码三区|久久视频爱久久免费精品

RELATEED CONSULTING
相關咨詢
選擇下列產品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網營銷解決方案
不用trycatch,如何機智的捕獲錯誤

起源
我們知道,React中有個特性Error Boundary,幫助我們在組件發(fā)生錯誤時顯示“錯誤狀態(tài)”的UI。

為了實現(xiàn)這個特性,就一定需要捕獲到錯誤。

所以在React源碼中,所有用戶代碼都被包裹在一個方法中執(zhí)行。

類似如下:

 
 
 
 
  1. function wrapper(func) { 
  2.   try { 
  3.     func(); 
  4.   } catch(e) { 
  5.     // ...處理錯誤 
  6.   } 

比如觸發(fā)componentDidMount時:

 
 
 
 
  1. wrapper(componentDidMount); 

本來一切都很完美,但是React作為世界級前端框架,受眾廣泛,凡事都講究做到極致。

這不,有人提issue:

 
 
 
 
  1. 你們這樣在try catch中執(zhí)行用戶代碼會讓瀏覽器調試工具的Pause on exceptions失效。 

Pause on exceptions失效的來龍去脈
Pause on exceptions是什么?

他是瀏覽器調試工具source面板的一個功能。

開啟該功能后,在運行時遇到會拋出錯誤的代碼,代碼的執(zhí)行會自動停在該行,就像在該行打了斷點一樣。

比如,執(zhí)行如下代碼,并開啟該功能:

 
 
 
 
  1. let a = c; 

代碼的執(zhí)行會在該行暫停。

這個功能可以很方便的幫我們發(fā)現(xiàn)未捕獲的錯誤發(fā)生的位置。

但是,當React將用戶代碼包裹在try catch后,即使代碼拋出錯誤,也會被catch。

Pause on exceptions無法在拋出錯誤的用戶代碼處暫停,因為error已經被React catch了。

除非我們進一步開啟Pause on caught exceptions。

開啟該功能,使代碼在捕獲的錯誤發(fā)生的位置暫停。

如何解決
對用戶來說,我寫在componentDidMount中的代碼明明未捕獲錯誤,可是錯誤發(fā)生時Pause on exceptions卻失效了,確實有些讓人困惑。

所以,在生產環(huán)境,React繼續(xù)使用try catch實現(xiàn)wrapper。

而在開發(fā)環(huán)境,為了更好的調試體驗,需要重新實現(xiàn)一套try catch機制,包含如下功能:

  • 捕獲用戶代碼拋出的錯誤,使Error Boundary功能正常運行
  • 不捕獲用戶代碼拋出的錯誤,使Pause on exceptions不失效

這看似矛盾的功能,React如何機智的實現(xiàn)呢?

如何“捕獲”錯誤
讓我們先實現(xiàn)第一點:捕獲用戶代碼拋出的錯誤。

但是不能使用try catch,因為這會讓Pause on exceptions失效。

解決辦法是:監(jiān)聽window的error事件。

根據GlobalEventHandlers.onerror MDN[1],該事件可以監(jiān)聽到兩類錯誤:

  • js運行時錯誤(包括語法錯誤)。window會觸發(fā)ErrorEvent接口的error事件
  • 資源(如