MST

星途 面试题库

面试题:JavaScript异步错误处理与事件循环的关系

阐述JavaScript异步错误(如在Promise、async/await中出现的错误)的处理机制,以及这些错误处理过程与事件循环机制之间的相互影响,结合具体代码示例进行说明。
36.8万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

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()中处理,这里不会再触发未捕获错误。