JavaScript

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > JavaScript稳定建设

JavaScript代码不能被阻断的稳定性建设

作者:bigtree

这篇文章主要为大家介绍了JavaScript代码不能被阻断的稳定性建设详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

背景

稳定性建设之JavaScript代码不能被阻断

js代码可能会因为某些原因,导致出错,进而整个后续代码有可能都被阻断。直接影响线上的稳定性

最常见的js被阻断的情况

console.log(111)
// 预期 a = {}
// 结果
a = undefined
a.a = 1
console.log(222) // js代码不能执行到这一行

这个代码很明显会报错,在a.a = 1这一行开始报错,后续的js代码被阻断了,console.log(222)打印不出来

解决办法

console.log(111)
try {
  // 预期 a = {}
  // 结果
  a = undefined
  a.a = 1
} catch (e) {
  console.error(e)
}
console.log(222) // js代码可以执行到这一行

容易被我们忽视的点

1. 没考虑到错误上报

try {
  // 预期 a = {} 
  // 结果 
  a = undefined 
  a.a = 1
} catch (e) {
  console.error(e)
  // 公司内部的上报函数
  someReportFunction('sendEvent', {
    name: 'try_catch_error',
    params: {
      errorMsg: e.message,
      errorStack: e.stack
    },
  });
}

2. 错用throw

随便点开一篇文章,就有人在误人子弟,教别人用 throwthrow这个东西是不能乱用的,因为他会阻断代码,重要的事情说三遍,throw会阻断代码,throw会阻断代码,throw会阻断代码

例如:

console.log(111)
try {
  // 预期 a = {}
  // 结果
  a = undefined
  a.a = 1
} catch (e) {
  console.error(e)
  throw e // throw会阻断代码,导致下面不执行
}
console.log(222) // 不能执行到这一行

当然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不到,还是会被阻断

console.log(111111111)
try {
  setTimeout(() => {
    a = undefined
    a.a = 1 // 代码被阻断于此
    console.log('error') // 不能执行到这一行
  }, 0)
} catch (e) {
  console.error(e) // 异步代码catch不到
}
console.log(222222222)
setTimeout(() => {
  console.log('setTimeout') // 浏览器可以执行到这一行,node的不行(node14和16版本都test了)
}, 2000)

4. import()和require()的错误捕获表现不一致

// a.js
console.log(111111111)
try {
  require('./b.js')
} catch (e) {
  console.log('error') // 错误会被正常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)
// 结果打印 (require被正常捕获)
111111111
1
error
TypeError: Cannot set property 'a' of undefined
    ...
    ...
222222222
setTimeout
// a.js
console.log(111111111)
try {
  import('./b.js')
} catch (e) {
  console.log('error') // 错误没有被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)
// 结果打印 (import的 错误没有被catch到)
111111111
222222222
1
(node:92673) UnhandledPromiseRejectionWarning: TypeError: Cannot set property 'a' of undefined
    ...
setTimeout

正确捕获import()的方式:其实import()是一个promise,用promise的方法去catch就好了

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

结论:

背景:

以上就是JavaScript代码不能被阻断的稳定性建设的详细内容,更多关于JavaScript稳定建设的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文