MST

星途 面试题库

面试题:JavaScript事件循环与Web API的交互原理

阐述JavaScript事件循环如何与Web API(如setTimeout、fetch等)进行交互。当有多个Web API调用和不同类型任务(宏任务、微任务)混合时,事件循环的具体执行流程是怎样的?
33.4万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
  1. JavaScript事件循环基础
    • JavaScript是单线程语言,这意味着它同一时间只能执行一个任务。事件循环机制让JavaScript能够处理并发操作。事件循环不断检查调用栈是否为空,当调用栈为空时,它会从任务队列中取出任务放入调用栈执行。
  2. Web API与事件循环的交互
    • setTimeout
      • 当执行到setTimeout函数时,它的回调函数并不会立即进入调用栈。setTimeout是由浏览器的Web API实现的。当setTimeout被调用时,它的时间参数开始倒计时,在倒计时结束后,Web API将其回调函数放入宏任务队列。
      • 例如:
setTimeout(() => {
    console.log('setTimeout callback');
}, 1000);
console.log('main script');

在这段代码中,首先输出main script,因为它在主调用栈中直接执行。1秒后,setTimeout的回调函数被放入宏任务队列,当调用栈为空时,该回调函数被取出并执行,输出setTimeout callback

  • fetch
    • fetch也是Web API的一部分。当fetch被调用时,它会发起一个网络请求。这个网络请求是异步的,不会阻塞JavaScript的执行。当网络请求完成(成功或失败),Web API会将fetchthen回调函数放入微任务队列(如果是链式调用then)或者宏任务队列(如果是直接在fetch调用后添加then,不同浏览器可能有差异,现代浏览器倾向于微任务)。
    • 例如:
fetch('https://example.com/api')
   .then(response => {
        console.log('fetch success callback');
        return response.json();
    })
   .catch(error => {
        console.log('fetch error callback');
    });
console.log('main script');

这里先输出main script,当fetch请求完成,then回调函数进入队列,待调用栈为空时执行,输出fetch success callback(假设请求成功)。 3. 宏任务和微任务混合时事件循环执行流程

  • 宏任务队列:常见的宏任务包括setTimeoutsetIntervalI/O操作、UI渲染等。
  • 微任务队列:常见的微任务包括Promise.thenMutationObserver等。
  • 执行流程
    • 首先执行全局的同步代码,将函数调用依次压入调用栈,执行完毕后清空调用栈。
    • 检查微任务队列,如果有微任务,将微任务依次压入调用栈并执行,直到微任务队列为空。
    • 然后检查宏任务队列,取出一个宏任务放入调用栈执行,执行完毕后再次检查微任务队列并清空微任务队列。
    • 如此循环,不断从宏任务队列取任务执行,执行完后清空微任务队列,这个过程就是事件循环。
    • 例如:
setTimeout(() => {
    console.log('setTimeout macro task');
}, 0);
Promise.resolve()
   .then(() => {
        console.log('Promise micro task');
    });
console.log('main script');

首先输出main script,然后清空微任务队列,输出Promise micro task,最后执行宏任务,输出setTimeout macro task