亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JavaScript代碼不能被阻斷的穩(wěn)定性建設(shè)

 更新時(shí)間:2022年10月10日 09:11:19   作者:bigtree  
這篇文章主要為大家介紹了JavaScript代碼不能被阻斷的穩(wěn)定性建設(shè)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

背景

穩(wěn)定性建設(shè)之JavaScript代碼不能被阻斷

js代碼可能會(huì)因?yàn)槟承┰颍瑢?dǎo)致出錯(cuò),進(jìn)而整個(gè)后續(xù)代碼有可能都被阻斷。直接影響線上的穩(wěn)定性

最常見的js被阻斷的情況

console.log(111)
// 預(yù)期 a = {}
// 結(jié)果
a = undefined
a.a = 1
console.log(222) // js代碼不能執(zhí)行到這一行

這個(gè)代碼很明顯會(huì)報(bào)錯(cuò),在a.a = 1這一行開始報(bào)錯(cuò),后續(xù)的js代碼被阻斷了,console.log(222)打印不出來

解決辦法

  • 解決辦法也很簡(jiǎn)單,用 try...catch... 捕獲住錯(cuò)誤就好了
console.log(111)
try {
  // 預(yù)期 a = {}
  // 結(jié)果
  a = undefined
  a.a = 1
} catch (e) {
  console.error(e)
}
console.log(222) // js代碼可以執(zhí)行到這一行

容易被我們忽視的點(diǎn)

1. 沒考慮到錯(cuò)誤上報(bào)

  • 上面的demo沒有考慮錯(cuò)誤上報(bào),發(fā)生錯(cuò)誤時(shí),外部根本捕獲不到(即使你接入了sentry類的產(chǎn)品),因?yàn)閑rror被try catch給吃掉了
try {
  // 預(yù)期 a = {} 
  // 結(jié)果 
  a = undefined 
  a.a = 1
} catch (e) {
  console.error(e)
  // 公司內(nèi)部的上報(bào)函數(shù)
  someReportFunction('sendEvent', {
    name: 'try_catch_error',
    params: {
      errorMsg: e.message,
      errorStack: e.stack
    },
  });
}

2. 錯(cuò)用throw

隨便點(diǎn)開一篇文章,就有人在誤人子弟,教別人用 throwthrow這個(gè)東西是不能亂用的,因?yàn)樗麜?huì)阻斷代碼,重要的事情說三遍,throw會(huì)阻斷代碼,throw會(huì)阻斷代碼,throw會(huì)阻斷代碼

例如:

console.log(111)
try {
  // 預(yù)期 a = {}
  // 結(jié)果
  a = undefined
  a.a = 1
} catch (e) {
  console.error(e)
  throw e // throw會(huì)阻斷代碼,導(dǎo)致下面不執(zhí)行
}
console.log(222) // 不能執(zhí)行到這一行

當(dāng)然throw也不是一無是處,但是,他只能在try{ 里面使用 },不能在try之外的地方使用throw,包括catch

console.log(111)
try {
  throw new Error(111)
} catch (e) {
  console.error(e)
}
console.log(222)
function getData () {
    if (...) {
        ...
    } else {
        throw new Error(111)
    }
}
console.log(111)
try {
  getData()
} catch (e) {
  console.error(e)
}
console.log(222)

3. 異步代碼catch不到,還是會(huì)被阻斷

console.log(111111111)
try {
  setTimeout(() => {
    a = undefined
    a.a = 1 // 代碼被阻斷于此
    console.log('error') // 不能執(zhí)行到這一行
  }, 0)
} catch (e) {
  console.error(e) // 異步代碼catch不到
}
console.log(222222222)
setTimeout(() => {
  console.log('setTimeout') // 瀏覽器可以執(zhí)行到這一行,node的不行(node14和16版本都test了)
}, 2000)

4. import()和require()的錯(cuò)誤捕獲表現(xiàn)不一致

// a.js
console.log(111111111)
try {
  require('./b.js')
} catch (e) {
  console.log('error') // 錯(cuò)誤會(huì)被正常catch到
  console.error(e)
}
console.log(222222222)
setTimeout(() => {
  console.log('setTimeout')
}, 2000)
// b.js
console.log(1)
a = undefined
a.a = 1
console.log(2)
// 結(jié)果打印 (require被正常捕獲)
111111111
1
error
TypeError: Cannot set property 'a' of undefined
    ...
    ...
222222222
setTimeout
  • 同樣的代碼換成,import()
// a.js
console.log(111111111)
try {
  import('./b.js')
} catch (e) {
  console.log('error') // 錯(cuò)誤沒有被catch到
  console.error(e) 
}
console.log(222222222)
setTimeout(() => {
  console.log('setTimeout')
}, 2000)
// b.js
console.log(1)
a = undefined
a.a = 1
console.log(2)
// 結(jié)果打印 (import的 錯(cuò)誤沒有被catch到)
111111111
222222222
1
(node:92673) UnhandledPromiseRejectionWarning: TypeError: Cannot set property 'a' of undefined
    ...
setTimeout

正確捕獲import()的方式:其實(shí)import()是一個(gè)promise,用promise的方法去catch就好了

import('./b.js') 
  .catch(e => { 
    console.log('error') 
    console.error(e) 
  })

結(jié)論:

  • try catch 不能捕獲import()模塊的錯(cuò)誤,require可以被捕獲
  • import() 用promise的方法去catch就好了

背景:

  • require是運(yùn)行時(shí)加載(可以理解為,函數(shù)調(diào)用)
  • import()是動(dòng)態(tài)import,會(huì)延遲加載,是異步任務(wù)(微任務(wù)),是promise

以上就是JavaScript代碼不能被阻斷的穩(wěn)定性建設(shè)的詳細(xì)內(nèi)容,更多關(guān)于JavaScript穩(wěn)定建設(shè)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論