假设代码块执行抛出错误 fail,那么捕获该错误的写法为:异步
try { // 代码块执行,并抛出 fail 错误 throw new Error('fail'); } catch (e) { console.log(e); }
咱们先来针对上面的代码改写一下,加入一个定时器。async
try { setTimeout(()=>{ throw new Error('fail'); // Uncaught Error: fail }, 1000); } catch (e) { console.log(e); }
像这样,将 try/catch 扔在定时器的外面,是没法捕获到内部的错误的。函数
正确的作法应该是:code
setTimeout(()=>{ try{ throw new Error('fail'); } catch (e) { console.log(e); } },1000);
function doSomething() { return new Promise((resolve, reject) => { // 同步代码中的 throw 能够被捕捉到 throw new Error('fail'); }); } doSomething() .then((x) => { console.log('success:', x); }) .catch((err) => { console.log('fail:', err); });
这样写是没有问题的,错误可以被捕获到。但只要稍微修改一下,可能就出现问题了。好比:同步
function doSomething() { return new Promise((resolve, reject) => { // 异步代码中的 throw 不能被 Promise 的 catch 捕捉到 setTimeout(() => { throw new Error("fail"); }, 1000); }); } doSomething() .then((x) => { console.log('success:', x); }) .catch((err) => { console.log('fail:', err); });
这里抛出但错误将不能被捕获。因此,在 Promise 中,咱们通常经过 reject 来抛出错误。it
function doSomething(x) { return new Promise((resolve, reject) => reject(x)); } doSomething('fail').then((x) => { console.log('success:', x); }).catch((err) => { console.log('fail:', err); }); // fail: fail
另外,还有一个比较有意思的细节,在 catch 以后继续添加 .then 会被继续执行。io
function doSomething(x) { return new Promise((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: undefined
本质上来说, Async/Await 是经过 Promise 实现,因此基本跟上面 Promise 所讲的差很少。console
能够在 await 方法外嵌套 try/catch,相似这样:function
function doSomething(x) { return new Promise((resolve, reject) => reject(x)); } (async () => { try { const result = await doSomething('fail'); console.log('success:', result); // return 返回 } catch (err) { console.log('fail:', err); // return 返回 } })(); // fail: fail
但这里就有一个问题,好比函数须要有返回,那么返回的语句就须要写两次,正常但时候返回结果,错误的时候,返回一个 throw new Error()
或者其余的。有一个小的窍门,能够这样写:class
function doSomething(x) { return new Promise((resolve, reject) => reject(x)); } (async () => { const result = await doSomething('fail').catch((err) => { console.log('fail:', err); return 0; // 默认值 }); console.log('success:', result); })(); // fail: fail // success: 0
在错误捕获到以后,从新分配一个默认值,让代码继续运行。