1. 主页 > 好文章

JavaScript异步代码异常捕技巧:try catch与Promise实战

鏄笉鏄粡甯搁亣鍒拌繖绉嶆儏鍐碉紵椤甸潰绐佺劧鐧藉睆锛屾帶鍒跺彴涓€鍫嗙孩瀛楁姤閿欙紝浣嗘牴鏈笉鐭ラ亾鍝噷宕╃殑锛熺壒鍒槸鐢ㄦ墜鏈烘墦寮€缃戦〉鏃讹紝鐢ㄦ埛鐩存帴娴佸け锛岃繛鎶ラ敊淇℃伅閮芥姄涓嶅埌锛佸埆鎱岋紝浠婂ぉ鍜变滑灏辨潵鑱婅亰寮傛浠g爜寮傚父鐨勫疄鎴樺鐞嗘妧宸э紝鎵嬫妸鎵嬫暀浣犵敤try/catch鍜孭romise鎼缓"閿欒闃叉姢缃?銆?/p>

锛堢敾澶栭煶锛氣€?strong>鈥?0%鐨勭嚎涓婂穿婧冮兘婧愪簬鏈崟鑾风殑寮傛閿欒鈥?/strong>鈥嬶紝杩欏彲涓嶆槸鍚撳敩浜猴紒锛?/p>


涓€銆佷负鍟ュ紓姝ラ敊璇繖涔堥毦鎶擄紵馃

鍏堟潵涓伒榄傛嫹闂細涓哄暐鍦╯etTimeout閲屾姏閿欙紝try/catch鎶撲笉鍒帮紵涓句釜渚嬪瓙浣犲氨鎳傦細

javascript澶嶅埗
try {
  setTimeout(() => {
    throw new Error('boom锛?); // 杩欓噷鐐镐簡
  }, 1000)
} catch(e) {
  console.log('鎶撳埌浣犱簡锛?) // 姘歌繙鎵ц涓嶅埌杩欓噷锛?/span>
}

鈥?strong>鈥嬪師鐞嗘彮绉樷€?/strong>鈥嬶細try/catch鏄?鍚屾瀹堝崼"锛岃€宻etTimeout鍥炶皟鏄?寮傛閫冪姱"銆傚綋閿欒鍦?绉掑悗鐖嗗彂鏃讹紝try/catch鏃╀笅鐝簡锛佽繖灏辨槸涓哄暐寰堝鏂版墜瑙夊緱"鏄庢槑鍔犱簡闃叉姢锛屼负鍟ヨ繕宕?鐨勬牴婧愩€?/p>


浜屻€乼ry/catch鐨勬纭墦寮€鏂瑰紡 馃攽

2.1 鍚屾鍦烘櫙锛氫竴鎶撲竴涓噯

javascript澶嶅埗
function 璁$畻鍣?) {
  try {
    const 缁撴灉 = 1 / 0; // 鏁呮剰瑙﹀彂鏃犵┓澶?/span>
    return 缁撴灉;
  } catch(e) {
    console.log('鎶撳埌闄や互闆堕敊璇細', e.message); // 杈撳嚭锛欼nfinity
  }
}

鈥?strong>鈥嬪垝閲嶇偣鈥?/strong>鈥嬶細杩欑鍗虫椂鍙戠敓鐨勯敊璇紝try/catch灏辨槸鍏嬫槦锛?/p>

2.2 寮傛鎴樺満锛氶渶瑕佸鎻?/h4>

鎺ュ紑澶寸殑闂锛屾纭Э鍔垮簲璇ユ槸锛?/p>

javascript澶嶅埗
setTimeout(() => {
  try {
    throw new Error('boom锛?);
  } catch(e) {
    console.log('杩欐鐪熸姄鍒颁簡锛?, e); 
  }
}, 1000)

鈥?strong>鈥嬫亶鐒跺ぇ鎮熸椂鍒烩€?/strong>鈥嬶細鎶妕ry/catch鎼繘寮傛鍥炶皟閲岋紝灏卞儚缁欐瘡涓揩閫掑寘瑁瑰崟鐙创闃叉憯鏍囩锛?/p>


涓夈€丳romise鐨勪笁绉嶉槻宕╁Э鍔?馃挭

3.1 鍩虹鐗堬細.catch褰撴姢鐩?/h4>
javascript澶嶅埗
fetch('/api鏁版嵁')
  .then(res => res.json())
  .then(data => {
    if(!data) throw new Error('绌烘暟鎹?); // 鎵嬪姩鎶涢敊
  })
  .catch(e => {
    console.log('鎺ュ彛寮傚父锛?, e); 
    return {code:500} // 闄嶇骇鏁版嵁
  });

鈥?strong>鈥嬪疄鎴樼粡楠屸€?/strong>鈥嬶細鏌愮數鍟咥PP鐢ㄨ繖鎷涳紝鎶婃敮浠樺け璐ョ巼浠?5%鍘嬪埌3%銆?/p>

3.2 杩涢樁鐗堬細async/await榛勯噾鎼。

javascript澶嶅埗
async function 鑾峰彇鐢ㄦ埛淇℃伅() {
  try {
    const 鍝嶅簲 = await fetch('/user');
    const 鏁版嵁 = await 鍝嶅簲.json();
    if(鏁版嵁.code !== 200) throw new Error(鏁版嵁.msg);
    return 鏁版嵁;
  } catch(e) {
    Sentry.captureException(e); // 涓婃姤鐩戞帶骞冲彴
    Toast.show('鍔犺浇澶辫触锛岃閲嶈瘯');
  }
}

鈥?strong>鈥嬪弻閲嶉槻鎶も€?/strong>鈥嬶細鏃㈡崟鑾风綉缁滈敊璇紝鍙堝鐞嗕笟鍔″紓甯革紝鍍忕粰浠g爜绌块槻寮硅。+閲戦挓缃┿€?/p>

3.3 缁堟瀬鐗堬細鍏ㄥ眬鍏滃簳

javascript澶嶅埗
// 鍏滀綇鎵€鏈夋紡缃戜箣楸?/span>
window.addEventListener('unhandledrejection', e => {
  console.error('Promise鍙涢€冭€咃細', e.reason);
  e.preventDefault(); // 闃绘鎺у埗鍙版姤绾?/span>
});

// 绀轰緥锛氬繕璁板啓catch鐨凱romise
Promise.reject(new Error('鎴戞槸婕忕綉楸?));

鈥?strong>鈥嬬洃鎺ф暟鎹€?/strong>鈥嬶細鎺ュ叆杩欏鏂规鍚庯紝鏌愯祫璁疉PP宕╂簝鐜囦笅闄?0%銆?/p>


鍥涖€侀伩鍧戞寚鍗楋紙琛€娉暀璁増锛?馃毀

4.1 缁忓吀韪╅浄鐜板満

javascript澶嶅埗
// 閿欒绀鸿寖锛氬湪then閲屽try/catch
fetchData()
  .then(res => {
    try { /* 瑙f瀽鏁版嵁 */ } 
    catch(e) { /* 鍙兘鎹曡幏瑙f瀽閿欒 */ }
  })
  .catch(e => { /* 鎹曡幏缃戠粶閿欒 */ });

// 姝g‘濮垮娍锛氱粺涓€鍦╝sync鍑芥暟澶勭悊
async function main() {
  try {
    const res = await fetchData();
    const data = await res.json();
  } catch(鍏ㄧ綉閿欒) {
    // 涓€缃戞墦灏斤紒
  }
}

鈥?strong>鈥嬫暀璁€荤粨鈥?/strong>鈥嬶細澶氬眰try/catch鍍忎縿缃楁柉濂楀▋锛岀淮鎶よ捣鏉ヨ鍛斤紒

4.2 閿欒绫诲瀷瀵规瘮琛?/h4>
閿欒绫诲瀷try/catch鎹曡幏.catch鎹曡幏鍏ㄥ眬鐩戝惉
setTimeout鎶涢敊鉂?/td>鉂?/td>鉁?/td>
Promise.reject鉂?/td>鉁?/td>鉁?/td>
async鍑芥暟鍐呴敊璇?/td>鉁?/td>鉁?/td>鉁?/td>
XMLHttpRequest鉂?/td>鉂?/td>鉁?/td>

锛堟暟鎹潵婧愶細鏌愮洃鎺у钩鍙?024骞寸粺璁℃姤鍛婏級


鐙瑙佽В锛氬紓甯稿鐞嗙殑涓夐噸澧冪晫

  1. 鈥?strong>鈥嬮潚閾滄浣嶁€?/strong>鈥嬶細鍝噷鎶ラ敊琛ュ摢閲岋紝姘歌繙鍦ㄦ晳鐏?br/> 锛堝父瑙佺幇璞★細鍦ㄦ瘡涓猣etch鍚庨潰澶嶅埗绮樿创.catch锛?/p>

  2. 鈥?strong>鈥嬮粍閲戞浣嶁€?/strong>鈥嬶細寤虹珛閿欒鐮佷綋绯伙紝鍍忓鐞咹TTP鐘舵€佺爜
    锛堝弬鑰冩渚嬶細鏌怬A绯荤粺瀹氫箟200+绉嶄笟鍔¢敊璇爜锛?/p>

  3. 鈥?strong>鈥嬬帇鑰呮浣嶁€?/strong>鈥嬶細鎶婇敊璇綋浜у搧闇€姹傝璁?br/> 锛堟渶浣冲疄璺碉細鏍规嵁閿欒绫诲瀷鑷姩闄嶇骇/閲嶈瘯/寮曞鐢ㄦ埛锛?/p>

鏈€杩戝府鏈嬪弸鍏徃閲嶆瀯浠g爜鏃跺彂鐜颁釜鏈夎叮鐜拌薄锛氣€?strong>鈥嬪畬鍠勭殑閿欒鐩戞帶鑳借寮€鍙戞晥鐜囨彁鍗?0%鈥?/strong>鈥嬶紒鍥犱负浠栦滑涓嶅啀琚敤鎴?椤甸潰鐧藉睆浜?鐨勬ā绯婂弽棣堟姌鑵撅紝鐩存帴鐪嬬洃鎺х湅鏃ュ織灏辫兘瀹氫綅闂銆?/p>


涓嬫褰撲綘鍐欏紓姝ヤ唬鐮佹椂锛岃寰楅粯蹇典笁閬嶏細鈥?strong>鈥嬮敊璇鐞嗕笉鏄鑳庯紝鏄畨鍏ㄦ皵鍥婏紒鈥?/strong>鈥?姣曠珶鐢ㄦ埛鍙笉浼氱粰浣犵浜屾鍔犺浇鐨勬満浼氾紝浣犺瀵瑰惂锛?/p>

本文由嘻道妙招独家原创,未经允许,严禁转载