一、为什么要解决异样

以前没有接触前端的时候我会想,平时咱们浏览的一些网页也好,app也好,为什么很少将一些bug啊、各种异样啊之类的货色出现在咱们用户的眼前,难道是程序运行的过程中都没有出现异常的状况吗?那必定不是的,那当初问题又来了,如果是呈现了异样,为什么咱们的用户在应用的过程中却简直没有察觉到?我感觉兴许这就是一款好的产品所必须的要点之一吧。试想,如果是因为各种突发的的异常情况就终止了整个程序的运行,那对用户来说真的是体验太差了!所以,咱们前端工作人员就很有必要去阻止这种事件的产生,那具体该如何去做呢?这就须要咱们前端在产生异样的时候就去捕捉该异样并去解决它,不要将一些不必要的异样出现给用户。好的,接下来咱们就简略来讨论一下对于前端解决异样的一些问题。

解决异样的n+个理由:

  • 加强用户体验;
  • 近程定位问题;
  • 防患未然,及早发现问题并去解决它;
  • 无奈复线问题,尤其是挪动端,机型,零碎都是问题;
  • 欠缺的前端计划,前端监控零碎;

对于 JS 而言,咱们面对的仅仅只是异样,异样的呈现不会间接导致 JS 引擎解体,最多只会使以后执行的工作终止。

二、前端须要做哪些异样捕捉

对于前端来说,咱们可做的异样捕捉还真的不少。总结一下,大略分为:

  • JS语法错误、代码异样
  • AJAX异样
  • 动态资源加载异样
  • Promise异样
  • Iframe异样
  • 跨域Script error
  • 解体和卡顿

对于异样解决,try-catch和Promise catch常常会被咱们常常用到,然而try-catch也会有一些我之前没有理解到的误区,Promise catch的性能也远比我之前理解的弱小的多。

那接下来,我就简略的剖析一下try-catch的误区和Promise catch的相干常识吧。

三、try-catch应用过程中的误区

  1. try-catch只能捕捉到同步的运行谬误,对语法和异步谬误去无能为力,捕捉不到。

(1)能够捕捉到同步的谬误

try {  let name = 'huangdonglu';  console.log(nam);//在这里成心把name写成了nam} catch(e) {  console.log('捕捉到异样:',e);}

输入:

捕捉到异样: ReferenceError: nam is not defined at <anonymous>:3:15

可见,同步的谬误能够被失常捕捉到。

(2)不能捕捉到语法的谬误

try {  let name = 'jartto;//在这里成心将左边的单引号去掉  console.log(nam);} catch(e) {  console.log('捕捉到异样:',e);}

输入:

Uncaught SyntaxError: Invalid or unexpected token

可见,语法的谬误不能被捕捉

(3)不能捕捉到异步的谬误

try {  setTimeout(() => {    undefined.map(v => v);//在这里设置成了undefined  }, 1000)} catch(e) {  console.log('捕捉到异样:',e);}

输入:

Uncaught TypeError: Cannot read property 'map' of undefined at setTimeout (<anonymous>:3:11)

可见,异步谬误也不能被捕捉

四、Promise Catch

Promise 链在错误处理中非常弱小,当一个promise被reject时,控制权移交至最近的reject处理程序(handler)。这在理论开发中十分不便。

promise catch的一个益处就是它能够链式应用,能够不必像try-catch语句那样多重的嵌套,只有在后面的链式过程中有任何一个中央出错,都会被catch捕捉到。

1.一般来说,咱们都会将.catch附加到链的开端,在这种状况下,只有上述的任何一个Promise被reject,catch就会捕捉它。

例如,上面这段代码:

new Promise((resolve, reject) => {  resolve("ok");}).then((result) => {  throw new Error("IU"); // reject 这个 promise}).catch(alert); // Error: IU!

2.Promise 的执行者(executor)和promise的处理程序(handler)四周有一个“隐式的"try-catch"。如果产生异样,它就会被捕捉,并被视为"rejection"进行解决。

例如:上面这段代码:

new Promise((resolve, reject) => {  throw new Error("IU!");}).catch(alert); // Error: IU!

与上面这段代码工作上完全相同:

new Promise((resolve, reject) => {  reject(new Error("IU!"));}).catch(alert); // Error: IU!

在executor四周的“隐式try-catch”主动捕捉了error,并将其变为rejected promise。

3.这不仅仅产生在executor函数中,同样也产生在handler中。如果咱们在.then处理程序(handler)中throw,这意味着promise被rejected,因而控制权移交至最近的error处理程序(handler)

例如,上面这一段代码:

new Promise((resolve, reject) => {  resolve("ok");}).then((result) => {  throw new Error("IU!"); // reject 这个 promise}).catch(alert); // Error: IU!

对于所有的error都会产生这种状况,而不仅仅是由throw语句导致的这些error。

例如,上面这一段代码:

new Promise((resolve, reject) => {  resolve("ok");}).then((result) => {  blabla(); // 没有这个函数}).catch(alert); // ReferenceError: blabla is not defined

最初的.catch不仅能够捕捉显示的rejection,还会捕捉它下面的处理程序(handler)中意外呈现的error。

4.在惯例的 try..catch 中,咱们能够剖析谬误(error),如果咱们无奈解决它,能够将其再次抛出。对于 promise 来说,这也是能够的。

上面的这个例子中,catch能够失常解决error,所以下一个胜利的.then处理程序(handler)就会被调用

// 执行流:catch -> thennew Promise((resolve, reject) => {  throw new Error("Whoops!");}).catch(function(error) {  alert("The error is handled, continue normally");}).then(() => alert("Next successful handler runs"));

catch能够失常解决异样,.then handler 也能够失常运行。

上面这个例子中,catch捕捉了异样,然而无奈解决它,所以就会将其再次抛出

// 执行流:catch -> catch -> thennew Promise((resolve, reject) => {  throw new Error("IU!");}).catch(function(error) { // (*)  if (error instanceof URIError) {    // 解决它  } else {    alert("Can't handle such error");    throw error; // 再次抛出此 error 或另外一个 error,执行将跳转至下一个 catch  }}).then(function() {  /* 不在这里运行 */}).catch(error => { // (**)  alert(`The unknown error has occurred: ${error}`);  // 不会返回任何内容 => 执行失常进行});

执行从第一个catch沿着链跳转到下一个catch

如果大家对Promise解决异样比拟感兴趣的话,这里有一篇好文章举荐给大家:应用Promise进行错误处理

五、总结

因为本文篇幅以及自己程度无限,所以只能在这里先简略介绍一下咱们平时比拟罕用的两种前端异样解决的伎俩,然而前端解决异样的办法还有很多,还须要咱们在一直的开发过程中去一直的学习。在这里举荐一篇比拟具体地介绍了各种前端解决异样办法的好文章给大家:如何优雅地解决前端异样,心愿可能帮忙到大家理解到更多的前端解决异样的方法。

总之,一个优良的开发者是要具备良好的解决问题的能力的,尽管有时候咱们不可预估这些问题什么时候呈现,然而咱们能够针对性的对可能会呈现的问题做好解决措施,这样即便问题真的呈现了,咱们也有相应的措施去进行解决。

有些货色咱们开发者晓得就好了,连忙把它偷偷解决掉,至于用户嘛,还是不要晓得为好,哈哈哈!skr!

本文参考链接:

1.如何优雅地解决前端异样

2.应用Promise进行错误处理