• 售前

  • 售后

热门帖子
入门百科

详解JavaScript错误捕获

[复制链接]
蓝天天使2017 显示全部楼层 发表于 2021-10-26 13:58:55 |阅读模式 打印 上一主题 下一主题
目录


  • 一、根本利用与逻辑
  • 二、特性
  • 三、错误对象
  • 四、较好的catch和throw计谋
  • 五、Promise的错误处理
  • 六、性能斲丧​

一、根本利用与逻辑


利用
  1. try{
  2.     //code....
  3. }catch(err){
  4.     //error handling
  5. }finally{
  6.     //no matter what happens in the try/catch (error or no error), this code in the finally statement should run.
  7. }
复制代码
逻辑


二、特性


try...catch 仅实用于运行时错误,解释阶段错误无法正常工作
  1. try{
  2.     {{{{{{{
  3. }catch(err){
  4.     console.error(err)
  5. }
  6. //引擎在‘parse-time'出错,导致无法理解代码,因此无法捕捉
复制代码
try...catch 只能同步工作
  1. try{
  2.     setTimeout(function(){
  3.         undefinedVariable;
  4.     },1000)
  5. }catch(err){
  6.     console.error(err)
  7. }
  8. //setTimeout的回调函数执行时,引擎已经离开try...catch结构
复制代码
finally 能让try块中的return语句失效
  1. function test(){
  2.   try {
  3.     return 1;
  4.   } catch(error) {
  5.     return 2;
  6.   } finally {
  7.     return 3;
  8.   }
  9. }
  10. console.log(test());
  11. //3
复制代码
三、错误对象


当步伐发生error,js内部会天生一个包含error细节的对象,该对象会被作为参数传进catch
对于全部内置错误,错误对象具有两个主要属性
       
  • name 错误范例   
  • message 文本范例的错误信息   
  • stack (非尺度属性)发生错误时的调用栈信息,主要用于调试
  1. try {
  2.   lalala; // error, variable is not defined!
  3. } catch (err) {
  4.   alert(err.name); // ReferenceError
  5.   alert(err.message); // lalala is not defined
  6.   alert(err.stack); // ReferenceError: lalala is not defined at (...call stack)
  7.   // Can also show an error as a whole
  8.   // The error is converted to string as "name: message"
  9.   alert(err); // ReferenceError: lalala is not defined
  10. }
复制代码
理论上,我们可以throw任何东西作为错误对象,但最好的习惯是throw一个具有name,message的对象,以便和内置错误对象保持兼容
番外:内置的错误对象
            对象            含义                                    ReferenceError            引用未定义变量时触发                            SyntaxError            利用不正当的语法布局时触发                            TypeError            值得范例非预期时触发                            URIError            错误利用全局URI函数如encodeURI()、decodeURI()等时触发                            RangeError            对Array构造函数利用错误的长度值,对Number.toExponential()、Number.toFixed()或Number.toPrecision()利用无效数字等                            EvalError            全局函数eval()中发生的错误        
四、较好的catch和throw计谋


​ catch错误不单单是为了防止步伐挂掉,更重要的目标是方便调试,找bug,以是对错误的处理计谋,稍微可以体现出码者的优雅性
​ 俗话说的好,码者,人恒雅也,尽量遵照一个原则,catch只处理本身知道的错误
举个梨子
  1. let json = '{ "age": 30 }';
  2. try{
  3.   let user = JSON.parse(json);  
  4.   alert( user.name );
  5. } catch (err) {
  6.   console.error('JSON Error:'+err);
  7. }
复制代码
上述例子的catch计谋能包管步伐正常,由于catch块能catch内部全部的错误,无论是JSON.parse堕落还是user.name不存在报错,都能被catch到,但两种错误都用同一种打印是不利于调试的,写成下面如许会好一点
  1. let json = '{"age":30}'
  2. try{
  3.   let user =  JSON.parse(json);
  4.   alert(user.name)
  5. }catch(err){
  6.    if(err instanceof SyntaxError){
  7.        console.error('JSON Error:'+err);
  8.    }
  9.    else throw err;
  10. }
复制代码
每个catch块处理本身知道得,可能会出现得错误,就是说,编程职员在编程的时候,catch那些预推测的错误,而将可能本身没推测的错误抛到表面。

五、Promise的错误处理


​ 众所周知,Promise是会吞掉error的,由于promise的实现就在内部对全部error举行了捕捉,且捕捉到的error不是向外抛出(外指promise之外),而是沿着链找到最近的onreject回调传入,以是promise的错误处理只有两种办法
       
  • 设置onreject回调   
  • 全局捕捉
举个栗子
  1. try{
  2.     new Promise((resolve,reject)=>{
  3.         throw new Error('promise error')
  4.     }).catch(()=>{
  5.         //错误在最近的onreject回调被捕获
  6.         console.error(err);
  7.     })
  8. }catch(err){
  9.     //永远不会执行,promise吞掉error
  10.     console.error(err);
  11. }
复制代码
别的需要留意,无论是实行者函数(executor)和还是 promise 的处理步伐(handler),内部发生的错误齐备吞掉,相当于被隐式catch,error会主动找到最近的onreject回调传进去
  1. try{
  2.     new Promise((resolve,reject)=>{
  3.         resolve();
  4.     }).then(()=>{
  5.         throw new Error('promise then error');
  6.     }).catch((err){
  7.         console.error(err);
  8.     })
  9. }catch(err){
  10.     //地球毁灭之前都不会执行
  11.     console.error(err)
  12. }
复制代码
同理,在错误找到onreject传进去之前,颠末的then注册的onfulfilled回调齐备失效,直到找到onreject回调,处理之后,onreject回调之后的onfulfilled回调才正常
  1. try {
  2.     new Promise((resolve, reject) => {
  3.         throw new Error('promise error')
  4.     }).then((ret) => {
  5.         //错误没有处理,失效
  6.         console.log('then1:' + ret)
  7.     }).catch((err) => {
  8.         //错误处理了,后序正常
  9.         console.error(err);
  10.         return 'handled'
  11.     }).then((ret) => {
  12.         //正常执行
  13.         console.log('then2' + ret);
  14.     })
  15. } catch (err) {
  16.     //同样的,人类毁灭之前都不会执行
  17.     console.error(err)
  18. }
  19. // Error:promise error
  20. //then2handled
复制代码
那整条链一个catch都没设置会怎么样呢?
那这个error就会击穿地心,不绝穿透到全局,根据宿主情况的不同触发不同的全局事件,比如说欣赏器中会触发 unhandledrejection事件,node情况中也会触发unhandledRejection事件,一般会对这事件举行监听,再显示信息给编程职员大概用户
番外1:chromium / v8 / v8 / 3.29.45 的 Promise内部错误捕捉

番外2:async/await错误捕捉

六、性能斲丧​

After V8 version 6 (shipped with Node 8.3 and latest Chrome), the performance of code inside try-catch is the same as that of normal code. ------ 爆栈网
(稍微测了一下,相差无几)
以上就是详解JavaScript错误捕捉的详细内容,更多关于JavaScript 错误捕捉的资料请关注草根技术分享别的干系文章!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作