裴大头-秦可爱

裴大头-秦可爱

JavaScript 的事件循环机制

发表于 2023-11-15
裴大头
阅读量 1665
更新于 2023-11-15

JavaScript 的事件循环机制(Event Loop)是一种管理和调度异步任务执行的机制,它确保 JavaScript 代码能够以非阻塞的方式执行。

JavaScript 运行时包含以下几个重要的组成部分:

  1. 调用栈(Call Stack):用于存储执行上下文(函数调用)的栈结构。当执行一个函数时,将其执行上下文推入调用栈,函数执行完成后将其弹出。调用栈是单线程执行的,同一时间只能执行一个任务。
  2. 消息队列(Message Queue):用于存储待执行的消息(任务)。每个消息都与一个或多个回调函数相关联。当异步任务完成后,会将其对应的回调函数推入消息队列。
  3. 事件循环(Event Loop):负责监听调用栈和消息队列,并决定何时将消息队列中的任务推入调用栈执行。事件循环不断地检查调用栈和消息队列的状态,并根据一定的规则进行调度。 image.png image.png

事件循环的基本流程如下:

  1. 执行同步任务:从全局上下文开始,按顺序执行同步任务,直到遇到第一个异步任务。
  2. 处理异步任务:当遇到异步任务时,会将其挂起并注册回调函数。异步任务可以是定时器、网络请求、事件监听等。
  3. 异步任务完成后:将其对应的回调函数推入消息队列。
  4. 判断调用栈是否为空:当调用栈为空时,事件循环会检查消息队列。
  5. 执行回调函数:将消息队列中的第一个任务(回调函数)推入调用栈执行。
  6. 重复上述过程:循环执行上述流程,保证异步任务得到处理并执行回调函数。

需要注意的是,事件循环机制中还存在微任务(Microtask)和宏任务(Macrotask)的概念,它们影响着异步任务的执行顺序和优先级。微任务具有比宏任务更高的优先级,会在当前宏任务执行完毕后立即执行。 通过事件循环机制,JavaScript 可以处理异步操作,并确保代码执行的非阻塞性,提供了一种灵活的方式来处理异步任务。

微任务(Microtask)和宏任务(Macrotask)都是在事件循环中用于处理异步操作的机制,它们之间有一些重要的区别。

微任务(Microtask)

  1. 执行时机:微任务会在当前宏任务执行完成后立即执行。也就是说,当一个宏任务执行完毕后,在开始下一个宏任务之前,会先检查是否存在微任务队列,如果有,则依次执行微任务队列中的所有任务。
  2. 优先级:微任务具有比宏任务更高的优先级。在事件循环中,微任务总是优先于宏任务执行,即使它们是在同一个事件循环阶段中产生的。
  3. 触发方式:常见的触发微任务的方式包括Promise的resolve/reject、MutationObserver以及Node.js中的process.nextTick等。
  4. 示例应用:微任务适合处理一些优先级较高、需要尽快执行的任务,例如处理状态更新、执行DOM操作后的回调等。

宏任务(Macrotask)

  1. 执行时机:宏任务会在当前事件循环的下一个阶段执行。在事件循环中,每个宏任务之间会有一个渲染帧的间隔,这样可以保证浏览器在执行宏任务时能够进行页面渲染和响应用户交互。
  2. 优先级:宏任务的优先级相对较低,在事件循环中会在微任务之后执行。
  3. 触发方式:常见的触发宏任务的方式包括setTimeout、setInterval、I/O操作、UI交互事件(如点击、滚动)等。
  4. 示例应用:宏任务适合处理一些耗时较长、优先级较低的任务,例如网络请求、定时器回调、用户交互事件回调等。

需要注意的是,微任务和宏任务的执行顺序是固定的:一个宏任务执行完毕后,会先检查并执行所有的微任务,然后再执行下一个宏任务。这种机制保证了微任务的即时性和优先级。 在实际开发中,合理使用微任务和宏任务可以提高代码的性能和响应能力。微任务适合处理一些重要的、需要立即执行的任务,而宏任务则适合处理一些延时较长或者对实时性要求不高的任务。

事件循环经典案例

事件循环经典案例

参考资料

什么是Event Loop?

评论
来发一针见血的评论吧!
表情

快来发表评论吧~

推荐文章
  • Vue项目代码规范

    1点赞1评论

  • JavaScript 的事件循环机制

    1点赞1评论

  • 聊一聊我的文本编辑器

    1点赞11评论

  • JavaScript的常用遍历方法整理

    1点赞8评论

  • 前端面试精选-基础篇

    1点赞0评论

Crafted with by Pei你看雪

小破站居然运行了 865 天访客 23350

© 2023 Pei你看雪鲁ICP备19037910号-2