我正在尝试捕获由异步javascript回调函数引起的错误,
try{
setTimeout(()=>{
throw err
console.log("after throw")
}, 1000)
}catch(e){
console.log("caught");
}
但是你们中的许多人可能知道 catch 块永远不会被执行,那么这里到底发生了什么?
我知道我可以使用承诺和异步/等待来实现类似的事情,
async foo(){
try{
await setTimeoutPromise(1000);
}catch(e){
alert("caught");
}
}
当你使用 setTimeout 时,回调被推送到事件循环中(移出 JS 引擎并进入运行时/浏览器领域(,你的foo
函数立即退出。
超时后,一旦堆栈为空,事件循环会将回调放到堆栈上并运行它。这就是为什么 try/catch 和回调是相互独立的。这也是为什么setTimeout(1000)
并不意味着在一秒钟内,但不早于一秒,并且有点接近一秒。
看看事件循环到底是什么? |菲利普·罗伯茨 |JSConf EU
这是两回事。
第一个代码不会捕获错误,因为它是异步发生的,并且try...catch
只会捕获同步引发的异常。
第二个代码将捕获错误,因为await
"同步"代码(使其外观和工作方式像是同步的(,并且错误仅由await
抛出:如果您没有使用它,您只会得到一个被拒绝的承诺(您真的不能从异步函数中抛出任何东西!
要使第一个代码正常工作,请将try...catch
移到回调中:
setTimeout(()=>{
try{
throw err
}catch(e){
console.log('catched')
}
console.log("after throw")
}, 1000)