ES5中传统方法假设代码块执行抛出错误fail,那么捕获错误的写法是:try{//代码块执行,并抛出失败错误thrownewError('fail');}catch(e){console.log(e);}定时器我们先重写上面的代码,添加一个定时器。try{setTimeout(()=>{thrownewError('fail');//UncaughtError:fail},1000);}catch(e){console.log(e);}像这样,会try/catch把它扔到定时器外面无法捕捉到内部错误。正确的做法应该是:setTimeout(()=>{try{thrownewError('fail');}catch(e){console.log(e);}},1000);PromisefunctiondoSomething(){returnnewPromise((resolve,reject)=>{//可以捕获同步代码中的抛出thrownewError('fail');});}doSomething().then((x)=>{console.log('success:',x);}).catch((err)=>{console.log('fail:',err);});这样写是没有问题的,可以捕获到错误。但是只要稍微修改一下,就可能会出现问题。例如:functiondoSomething(){returnnewPromise((resolve,reject)=>{//throw异步代码不能被PromisecatchsetTimeout(()=>{thrownewError("fail");},1000);});}doSomething().then((x)=>{console.log('成功:',x);}).catch((err)=>{console.log('失败:',呃);});这会被抛出,但错误不会被捕获。所以在Promise中,我们一般都是通过reject来抛出错误。functiondoSomething(x){returnnewPromise((resolve,reject)=>reject(x));}doSomething('fail').then((x)=>{console.log('success:',x);}).catch((err)=>{console.log('fail:',err);});//fail:fail另外还有一个有意思的细节,在catch之后加.then会继续。functiondoSomething(x){returnnewPromise((resolve,reject)=>reject(x));}doSomething('fail').then((x)=>{console.log('success:',x);}).catch((err)=>{console.log('fail:',err);//这里可以写return到下面的方法继续执行}).then((x)=>{console.log('continue:',x);});//fail:fail//continue:undefinedAsync/AwaitAsync/Await本质上是通过Promise实现的,所以和上面说的Promise基本一样。你可以在await方法之外嵌套try/catch,像这样:awaitdoSomething('fail');console.log('success:',result);//return返回}catch(err){console.log('fail:',err);//return返回}})();//fail:失败,但是这里有问题。比如函数需要返回,那么return语句就需要写两遍。它是正常的,但在正常时返回结果。错误时,返回一个thrownewError()或other。这里有一个小技巧,可以这样写:fail').catch((err)=>{console.log('fail:',err);return0;//默认值});console.log('success:',result);})();//fail:fail//success:0捕获到错误后,重新赋一个默认值,让代码继续运行。
