面试题答案
一键面试1. JavaScript异步错误处理机制
Promise中的错误处理
在Promise中,通过.catch()
方法来捕获异步操作中抛出的错误。当Promise被拒绝(rejected)时,.catch()
回调函数会被执行。
function asyncTask() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('异步操作出错'));
}, 1000);
});
}
asyncTask()
.then(result => console.log(result))
.catch(error => console.error('捕获到错误:', error));
上述代码中,asyncTask
返回的Promise在1秒后被拒绝并抛出错误,.catch()
捕获到这个错误并打印错误信息。
async/await中的错误处理
async
函数返回一个Promise对象,await
只能在async
函数内部使用。await
后的Promise如果被拒绝,会抛出错误,可以通过try...catch
块来捕获。
async function asyncFunction() {
try {
await asyncTask();
} catch (error) {
console.error('捕获到错误:', error);
}
}
asyncFunction();
这里asyncFunction
使用try...catch
捕获await asyncTask()
可能抛出的错误。
2. 与事件循环机制的相互影响
JavaScript的事件循环机制负责处理异步任务。当一个异步操作(如Promise或setTimeout
)完成时,它的回调函数会被放入任务队列(macro - task队列或micro - task队列,Promise的回调在micro - task队列)。
当执行栈为空时,事件循环会从micro - task队列中取出任务执行,直到micro - task队列为空,然后再从macro - task队列中取出一个任务放入执行栈执行。
错误处理在这个过程中遵循同样的规则。例如,当Promise被拒绝时,.catch()
回调会被放入micro - task队列,等待执行栈为空时执行。
console.log('开始');
new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('异步错误'));
}, 0);
})
.catch(error => {
console.error('捕获到错误:', error);
});
console.log('结束');
输出结果为:
开始
结束
捕获到错误: Error: 异步错误
首先,console.log('开始')
和console.log('结束')
在主线程执行栈中依次执行。setTimeout
的回调被放入macro - task队列,Promise的.catch()
回调被放入micro - task队列。当执行栈为空时,事件循环先处理micro - task队列,所以.catch()
回调在setTimeout
回调之前执行。最后执行setTimeout
回调,但由于错误已在.catch()
中处理,这里不会再触发未捕获错误。