激光切割机排版软件

· · 2373 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

激光切割机排版软件【电同微I7I54833762】try/catch基本上是大家最常和async/await的,基本上我们会用它去包围大部分的异步方法。await关键字后面的promise一旦reject了,就会抛出一个异常错误。

run();asyncfunctionrun(){try{awaitPromise.ject(newError('Oops!'));    }catch(err) {console.error(error.message);    }}复制代码

try/catch同样也可以处理同步的错误,比如下面:

asyncfunctionrun(){constv =null;try{awaitPromise.resolve('foo');    v.thisWillThrow;  }catch(error) {// 会出现"TypeError: Cannot read property 'thisWillThrow' of null"console.error(error.message);  }}复制代码

好像我们只要无脑把逻辑都放到try/catch里面就万事大吉了吗?不太准确,下面的代码却会导致unhandled promise rejection。这个return关键字直接返回就错误却不会被捕获:

asyncfunctionrun(){try{// 直接返回Promise,而不是用await关键字returnPromise.reject(newError('Oops!'));    }catch(error) {console.error(error.message);            }}复制代码

一种处理方式是使用return await来解决。

try catch捕获不了回调函数。try catch 仅仅在单一执行环境中奏效。

是在回调中加入try catch 来捕获错误。

setTimeout(funciton() {try{    fn()  }catch(e) {// handle error}                    })复制代码

这是奏效的。 不过try catch会在各个地方。 V8引擎是不鼓励try catch在函数中的使用的。 之前把try catch移到顶层来捕获调用栈的错误,但这个对异步代码不会奏效。

2. Golang-style(then)

golang style即使用.then()的方法来将一个promise转换为另一个处理完错误的reject promise。可以使用类似if(err)来进行检查:

asyncfunctionthrowAnError(){thrownewError('Opps!');}asyncfunctionrunAwait(){leterr =awaitthrowAnError();if(err){console.error(err.message);    }}复制代码

这么写会直接抛出异常,因为这个方法抛出了异常,但是该方法本身没有用try/catch捕获。很多时候,我们在使用第三方库的时候可能会出现这种情况。

then()解决方法

asyncfunctionrunAwait(){leterr =awaitthrowAnError().then(()=>null, err => err);if(err){console.error(err.message);    }}复制代码

then()的方式,就会等待promise状态resolve或reject后然后执行相应的回调,然后判断err对象并处理,所以其实它相当于被捕获了。

同时返回错误和值

asyncfunctionrun(){let[err, res] =awaitthrowAnError().then(v=>[null, v], err => [err,null]);if(err){console.error(err.message);    }console.log(res)}复制代码

结果:

这么做可以通过解构返回一个数组,包含了结果和error对象。当然如果是reject就会返回null和error对象;而如果resolved返回数组的第一个error对象就为null,第二个就是结果。

优缺点

优点:这种模式可以更简洁地处理,同时可以不需要写catch。

缺点1:这是非常重复性的,每次执行异步操作都需要去判断error对象。

缺点2:无法帮助处理run方法中的同步错误。所以这种方式需要谨慎使用。

3. Catch捕获

上面两种模式都可以处理异步错误,但是对于错误处理,最好的情况是在异步逻辑的最后加上catch,这样可以保证所有错误都被捕获到。其实这也是一个原则,即统一处理错误,而不是单独去处理每个错误

asyncfunctionrun(){returnPromise.reject(newError('Oops!'));}run().catch(functionhandleError(err){console.error(err.message);}).catch(err=>{    process.nextTick(()=>{throwerrl});})复制代码

使用catch捕获错误,如果handleError本身也有错误,就需要再catch一遍,但是为了避免回调地狱,如果该方法发生了错误就终止该进程。

优缺点

使用catch的话,不管异步方法本身是否捕获错误,它都会去捕获异步错误。

使用try/catch无法避免catch本身抛出异常,而如果它抛出了那除了嵌套多一层try/catch外,最好的做法就是加catch来让代码更简洁。

4  全局错误捕获

4.1 浏览器全局错误捕获

浏览器全局处理基本上就是依靠事件,因为浏览器是事件驱动的。一旦抛出错误,解释器在执行环境上下文中停止执行并展开,此时会有一个onerror全局事件抛出:

window.addEventListener('error',function(e){varerror = e.error;console.log(error);})复制代码

全局错误处理器会捕获任何在执行环境中发生的错误,即便是不同的对象发生的错误事件,或者是各种类型的错误。这是全局集中处理错误的一种常见方式。

调用栈

调用栈在定位问题的时候十分重要,我们可以使用调用栈在处理器中处理特定的错误。

window.addEventListener('error',function(e){varstack = e.error.stack;varmessage = e.error.toString();if(stack) {    message +='\n'+ stack;  }varxhr =newXMLHttpRequest();  xhr.open('POST','/log',true);// Fire an Ajax request with error detailsxhr.send(message);});复制代码

通过日志可以看到,具体什么情况触发了什么错误。在调试时调用堆栈也会非常有用。你 可以分析log,看到什么条件下触发了错误。

注意:如果跨域脚本是不会看到错误的。 在JS中,错误信息仅仅是允许在同一个域中。

个人想法

更多的时候,代码抛出了异常,我们更关注的是在运行时,某个变量的值是什么,是否这个变量的值导致了错误,所以打印出调用时的跟多的信息更重要。

4.2 Node.js全局错误捕获

Node.js本身的异常处理要复杂得多,因为涉及到了进程或线程抛出异常的问题。

基于Koa的全局错误处理

nodejs是error-first的异步处理机制,此处底层会调用net模块的listen方法并在错误发生时执行回调。

app.listen(app.config.listenPort, (err) => {if(err)throwerr  app.logger.info(`> Ready on http://localhost:${app.config.listenPort}`)})复制代码

路由错误处理

对于每个路由,它可能也会有不同的错误处理逻辑,这时路由进来的请求就需要根据情况返回不同的异常码和信息。

router.get('/loginAuth',async(ctx, next) => {try{constcode = query.codeconstres =awaitrequestToken(code)if(res.data.code !==0) {      ctx.app.logger.error(`request token error.Code is${res.data.code}|| response is:${JSON.stringify(res.data.data)}|| msg:${res.data.message}`)      ctx.body = {code:10000,message:`request token by code error`}    }else{      ctx.body = res.data    }  }catch(err) {    ctx.app.logger.error(`request api has exception${ctx.request.url}||${err.code}||${err.message}||${err.stack}`)    ctx.body = {code:500,message:`Error response`}  }})复制代码

5. 总结

通常异常可能是预期的或者超出预期的,不管怎样,使用try/catch没有问题。

对于超出预期的错误,尽量使用catch来保证它们会被捕获到。

把错误处理器添加到window对象上,它会捕获到异步错误。符合了DRY和SOLID原则。一个全局的错误处理器会帮你保持异步代码整洁。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:

查看原文:激光切割机排版软件

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

2373 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传