你知道吗?JavaScript中的事件循环机制

事件循环

事件循环是大多数现代应用程序(如JavaScript运行时环境、Node.js以及许多GUI工具包)用来处理并管理异步操作的核心机制。它允许程序执行非阻塞I/O操作,并且在操作完成时通过回调或者承诺(Promises)通知程序。

工作原理 :事件不断循环去查找和执行任务队列中的任务。当遇到异步操作时 例如:网络请求或者时文件读取就会把其交给系统处理并且同时执行其后续代码。等到这些异步处理完成之后它们的结果就会被加入到任务队列等待事件循环处理。

应用实例 : 在Web开发中,浏览器使用事件循环来处理用户交互(如点击和输入)、异步网络请求等,这里小编就介绍一下JS中的事件循环机制。

1. event loop

JavaScript 的事件循环(event loop)是该语言处理异步代码执行的核心机制。它负责执行异步代码并管理调用栈与任务队列之间的交互,确保异步操作。例如:定时器setTimeout , promises 和 I/O 操作能够在适当的时候被执行。简而言之事件循环使得JavaScript能够处理并操作并无需多线程

核心概念

  1. 调用栈(Call Stack)

    • 调用栈是一个后进先出的数据结构,用于跟踪当前正在执行的函数。每当一个函数被调用时,它就会被添加到调用栈中,并在函数执行完毕后从栈中移除。
  2. 任务队列(Task Queue)

    • 任务队列存储了所有等待被执行的任务。例如,由setTimeoutaddEventListener注册的回调函数会被放入任务队列中。
  3. 微任务队列(Microtask Queue)

    • 微任务队列包含所有需要尽快执行的任务,如Promise的回调、MutationObserver回调等。微任务队列的优先级高于普通任务队列。
  4. 事件循环

    • 事件循环不断地检查调用栈是否为空。如果调用栈为空,则会从任务队列或微任务队列中取出任务并将其推入调用栈执行。

宏任务与微任务

在 JavaScript 中,异步任务被分为两类:宏任务和微任务。宏任务主要包括 setTimeoutsetInterval 等操作,它们的回调函数会被放入一个先进先出(FIFO)队列中等待执行。相比之下,微任务主要由 promises 构成,同样遵循 FIFO 原则,但会在每次执行完同步代码后立即清空队列中的所有微任务。

事件循环的工作流程

事件循环的运行机制可以概括为以下几个步骤:

  1. 同步任务执行:首先,执行当前的同步任务,直至调用栈为空。
  2. 微任务队列清空:一旦调用栈为空,事件循环会检查并清空所有的微任务队列,确保这些微任务得到及时处理。
  3. 页面渲染:如果需要,浏览器会进行页面渲染操作。
  4. 宏任务队列处理:接着,从宏任务队列中取出一个任务执行。注意,每次只处理一个宏任务,以避免长时间阻塞主线程。
  5. 进入 idle 回调:最后,若无其他任务待处理,事件循环将进入 idle 状态,并可能触发一些低优先级的任务或垃圾回收等操作。
  • 执行顺序
markdown 复制代码
1.  `console.log('Start')`:输出"Start"。
1.  `setTimeout`:设置一个0毫秒的定时器,但它的回调不会立即执行,而是被放到任务队列中。
1.  `Promise.resolve().then()`:这是一个微任务,其回调会被放入微任务队列。
1.  `console.log('End')`:输出"End"。
1.  调用栈为空,处理微任务队列,输出"Promise"。
1.  处理任务队列,输出"Timeout"。

因此,最终的输出顺序为:"Start", "End", "Promise", "Timeout"。

注意事项

整个 script 本身被视为一个宏任务。此外,使用 async/await 关键字实际上是利用了 promise 实现的一种语法糖,其本质仍属于微任务范畴。当创建一个新的 promise 并调用 .then() 方法时,相应的回调会被添加到微任务队列中等待后续执行。

相关推荐
诗书画唱2 分钟前
【前端面试题】JavaScript 核心知识点解析(第二十二题到第六十一题)
开发语言·前端·javascript
excel9 分钟前
前端必备:从能力检测到 UA-CH,浏览器客户端检测的完整指南
前端
前端小巷子15 分钟前
Vue 3全面提速剖析
前端·vue.js·面试
悟空聊架构22 分钟前
我的网站被攻击了,被干掉了 120G 流量,还在持续攻击中...
java·前端·架构
CodeSheep23 分钟前
国内 IT 公司时薪排行榜。
前端·后端·程序员
尖椒土豆sss27 分钟前
踩坑vue项目中使用 iframe 嵌套子系统无法登录,不报错问题!
前端·vue.js
遗悲风28 分钟前
html二次作业
前端·html
江城开朗的豌豆32 分钟前
React输入框优化:如何精准获取用户输入完成后的最终值?
前端·javascript·全栈
CF14年老兵32 分钟前
从卡顿到飞驰:我是如何用WebAssembly引爆React性能的
前端·react.js·trae
画月的亮35 分钟前
前端处理导出PDF。Vue导出pdf
前端·vue.js·pdf