面试题 - 事件循环机制

本文详细解析了JavaScript的异步执行机制,包括单线程模型、事件循环、任务队列、宏任务与微任务的概念。浏览器中的多线程如何与JS引擎协同工作,确保异步操作不阻塞主线程。通过实例分析了任务执行顺序,揭示了setTimeout和Promise.then等异步操作的执行细节,并探讨了定时器误差产生的原因。
摘要由CSDN通过智能技术生成

面试题 - 事件循环机制

一、浏览器JS异步执行的原理

一般常说js是一门单线程语言,那为什么可以异步执行且不发生阻塞呢?

  • 常说的JS是单线程语言,是因为执行JS的引擎是单线程的,而浏览器本身是多线程的
  • 浏览器主要含有:
    • js 执行线程
    • 定时器线程
    • http 请求线程
    • 事件触发线程
    • GUI 线程等
  • 异步请求的真正执行者是浏览器的其他线程
  • js 引擎只是执行了异步操作成功了之后的回调函数

二、事件循环机制

1 - 执行栈和任务队列

(1)执行栈是什么

  • 用于按执行顺序存放同步代码
  • 按序执行,执行完毕后弹出执行栈
  • 如果在执行过程中遇到异步操作,就交给其他线程处理

(2)任务队列

  • 用于按序排放异步操作执行结束后的回调函数
  • 任务队列中的函数等待执行栈执行结束后取出执行

2 - 事件循环的本质

  • 基于事件驱动模式
  • 至少包含了一个事件循环来判断当前的任务队列是否有新的任务
  • 通过不断的循环取出异步回调进行执行

3 - 宏任务和微任务

(1)宏任务的分类

  • 渲染事件
  • 用户交互事件
  • SetTimeout、setInterval
  • 网络请求、文件读写等

有明确异步操作的任务,需要其他的异步线程支持

(2)微任务的分类

  • promise.then promise.catch
  • process.nextTick

没有明确的异步任务需要执行,只有回调不需要其他异步线程的支持

(3)执行顺序

  • 在同步代码执行结束后
  • 先执行微任务队列中的微任务
  • 再执行宏任务队列中的宏任务

(4)案例

console.log('同步代码1');
setTimeout(() => {
    console.log('setTimeout')
}, 0)
new Promise((resolve) => {
  console.log('同步代码2')
  resolve()
}).then(() => {
    console.log('promise.then')
})
console.log('同步代码3');

// 最终输出"同步代码1"、"同步代码2"、"同步代码3"、"promise.then"、"setTimeout"
setTimeout(() => {
  console.log('setTimeout start');
  new Promise((resolve) => {
    console.log('promise1 start');
    resolve();
  }).then(() => {
    console.log('promise1 end');
  })
  console.log('setTimeout end');
}, 0);
function promise1() {
  return new Promise((resolve) => {
    console.log('promise2');
    resolve();
  })
}
async function async1() {
  console.log('async1 start');
  await promise1();
  console.log('async1 end');
}
async1();
console.log('script end');

// 输出结果
async1 start
promise2
script end
async1 end
setTimeout start
promise1 start
setTimeout end
promise1 end

4 - 定时器误差

(1)执行顺序

  • 遇到一个定时器请求,开启定时器线程去计时
  • 计时结束后将回调函数放入到任务队列(宏任务)
  • 等待同步任务执行 waiting… ,在同步任务执行结束后可能还有微任务
  • 同步任务执行结束后取出任务队列中的回调

(2)误差大小

  • 定时器的误差值取决于同步任务的执行时间 + 微任务的执行时间
  • 同步任务执行时间越长,定时器的误差越大

三、脑图总结

在这里插入图片描述

好的,我会尽力回答您的问题。前端事件循环机制是指在浏览器中,所有的 JavaScript 代码都是通过事件循环来执行的。事件循环是一种机制,用于协调 JavaScript 代码的执行顺序,以确保所有的代码都能够按照正确的顺序执行。下面是一个简单的前端事件循环机制面试题: 1. 请简述前端事件循环机制的执行流程。 答:前端事件循环机制的执行流程主要包括以下几个步骤: 1)收集任务:将所有需要执行的任务加入到任务队列中。 2)执行任务:根据任务队列中的任务类型,将其分为宏任务和微任务。 3)执行宏任务:从宏任务队列中获取一个宏任务进行执行。 4)执行微任务:在宏任务执行期间,如果产生了微任务,将其加入到微任务队列中。 5)清空微任务:在宏任务执行结束后,清空微任务队列中的所有任务。 6)重复执行:重复执行步骤 3~5,直到任务队列中没有任务可以执行。 2. 请简述宏任务和微任务的区别。 答:宏任务和微任务是前端事件循环机制中的两种任务类型。宏任务是指一些较为耗时的任务,比如 setTimeout、setInterval、ajax 请求等。而微任务是指一些较为简单、执行时间较短的任务,比如 Promise.then、MutationObserver 等。 宏任务和微任务的执行顺序有所不同,具体来说,宏任务会在本轮事件循环的末尾执行,而微任务会在本轮事件循环的末尾执行完所有的宏任务后立即执行。这也就是为什么在 Promise.then 中产生的微任务会先于 setTimeout 中的宏任务执行的原因。 希望我的回答能够对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值