当前位置: 首页 > article >正文

什么是javascript的事件循环

JavaScript 的 事件循环(Event Loop) 是其执行机制的核心,用来处理异步操作,使得 JavaScript 能够实现非阻塞式的单线程异步编程。为了理解事件循环,首先要了解 JavaScript 是单线程的语言,这意味着它一次只能执行一个任务。但在实际应用中,比如 I/O 操作(网络请求、定时器、用户事件等),JavaScript 使用事件循环机制来管理异步任务,使其在需要的时候能继续执行而不阻塞主线程。

1. JavaScript 执行模型概览

JavaScript 的执行环境中包括以下几个关键概念:

  • 调用栈(Call Stack):调用栈是 JavaScript 用来管理函数执行的地方。当一个函数被调用时,它会被压入调用栈,执行完成后弹出。

  • 任务队列(Task Queue):也叫 消息队列(Message Queue),存放异步任务的回调函数,如 setTimeoutPromise、事件处理函数等。

  • 事件循环(Event Loop):事件循环是负责检查调用栈是否为空,并决定何时将任务队列中的任务推入调用栈执行的机制。

2. 事件循环的运行机制

事件循环的核心工作流程如下:

  1. 同步任务:所有同步任务都会直接在 调用栈(Call Stack) 上依次执行。

  2. 异步任务:当遇到异步任务(如 setTimeoutPromise、I/O 操作)时,这些任务会被放到相应的 任务队列 中,而不会立即执行。

  3. 事件循环(Event Loop):事件循环会不断检查调用栈是否为空。当调用栈为空时,它会查看 任务队列 是否有可执行的任务。如果有,它会将任务队列中的第一个任务放入调用栈中执行。

  4. 继续执行:当某个异步任务的回调函数被执行完,事件循环会再次检查任务队列,重复上述过程。

3. 宏任务和微任务

JavaScript 中的异步任务大致可以分为 宏任务(Macro-task)微任务(Micro-task),这两者的执行顺序是事件循环中至关重要的部分。

  • 宏任务(Macro-task)包括:setTimeoutsetIntervalI/O 操作、script(整体代码)、事件监听器等。

  • 微任务(Micro-task)包括:Promise.then()process.nextTick(Node.js)、MutationObserver

执行顺序:
  1. 事件循环每次循环称为一个 tick,每次 tick 开始时,会先执行 调用栈中的所有同步任务

  2. 当调用栈为空后,会执行 微任务队列(Micro-task Queue) 中的所有任务,直到微任务队列清空。

  3. 在微任务执行完毕之后,事件循环才会去执行下一个 宏任务队列 中的任务。

  4. 重复以上步骤。

示例:
console.log('Start'); // 同步任务

setTimeout(() => {
  console.log('Macro-task: setTimeout'); // 宏任务
}, 0);

Promise.resolve().then(() => {
  console.log('Micro-task: Promise'); // 微任务
});

console.log('End'); // 同步任务

执行顺序

  1. console.log('Start')console.log('End') 是同步任务,直接进入调用栈依次执行。
  2. setTimeout 是宏任务,它的回调函数会被放入宏任务队列中,稍后执行。
  3. Promise.then 是微任务,微任务会在同步任务结束后立即执行。
  4. 最后,setTimeout 的回调才会执行。

输出结果

Start
End
Micro-task: Promise
Macro-task: setTimeout

4. 典型的异步操作

  • setTimeoutsetInterval:它们是常见的定时器函数,回调函数会被放入宏任务队列中,等待事件循环调度。

  • PromisePromise 是微任务,它的 thencatch 回调会被放入微任务队列中,优先于宏任务执行。

  • requestAnimationFrame:这个函数专门用于高效的动画渲染,在浏览器的帧刷新之前执行其回调。

  • I/O 操作:如网络请求的回调会在 I/O 事件完成后放入宏任务队列中。

5. 事件循环在浏览器和 Node.js 中的区别

  • 浏览器 中,事件循环的机制更侧重于处理用户事件和 UI 渲染。每次事件循环中的宏任务执行完之后,浏览器会重新渲染页面,然后再执行下一个任务。

  • Node.js 的事件循环更复杂一些,尤其在处理 I/O 和定时器方面有更详细的阶段划分。Node.js 的事件循环大致分为几个阶段:timers 阶段(执行定时器回调)、I/O callbacks 阶段、idle, prepare 阶段、poll 阶段(处理 I/O 事件)、check 阶段(执行 setImmediate)、close 阶段(关闭回调)。

6. 事件循环的应用场景

  • 异步编程:事件循环机制使得 JavaScript 能够在单线程中高效处理 I/O 操作、定时器、DOM 操作等任务,不会阻塞主线程。

  • 优化性能:在用户界面更新时,长时间的同步任务可能导致页面卡顿,理解事件循环可以帮助你将耗时的任务异步处理,从而保持页面的流畅度。

  • 微任务与宏任务优化:通过合理使用微任务和宏任务,你可以控制任务的优先级,从而优化程序的执行顺序。

总结:

  • 事件循环 是 JavaScript 中实现异步编程的核心机制,它不断检查调用栈和任务队列,确保异步任务在适当的时间点执行。
  • 异步任务分为 宏任务微任务,微任务的优先级高于宏任务。
  • 事件循环的机制使得 JavaScript 能够处理大量 I/O、定时器、DOM 操作等任务而不阻塞主线程执行。

理解事件循环对于编写高效、流畅的 JavaScript 代码至关重要。


http://www.kler.cn/news/326088.html

相关文章:

  • 如何使用ssm实现基于BS的库存管理软件设计与实现+vue
  • 河南移动:核心营业系统稳定运行超300天,数据库分布式升级实践|OceanBase案例
  • SpringCloud 2023 LoadBalancer介绍、使用、获取服务列表原理、负载均衡算法
  • 【2024保研经验帖】中科院信工所夏令营经验分享
  • 【Git原理与使用】Git初识基本操作
  • 企业微信 标准年级对照表
  • Spring MVC系统学习(三)——数据绑定和响应
  • Lombok 在 IntelliJ IDEA 中的使用步骤
  • 可注射、自修复水凝胶胶粘剂:无缝合伤口闭合的新突破
  • 3. go 运算符
  • WSL2Linux 子系统(十一)
  • 简易CPU设计入门:取指令(三),ip_buf与rd_en的非阻塞赋值
  • chatgpt的ai导师风格设置
  • [ RK3566-Android11 ] 关于移植 RK628F 驱动以及后HDMI-IN图像延迟/无声等问题
  • Tesla T4 P2P测试
  • Vue 实现原生表格 tr td 动态合并 vue前端原生表格动态合并列 合并行
  • win10专业版永久关闭自动更新功能
  • Linux中配置docker环境
  • 基于Arduino的自弹尤克里里机器人
  • Apache DolphinScheduler-1.3.9源码分析(一)
  • Gromacs位置限制问题
  • 强化学习在自动驾驶技术中的应用与挑战
  • Spring 的作用和优势
  • [Linux#60][HTTPS] 加密 | 数字指纹 | 详解HTTPS工作方案 | CA认证
  • DOM中的节点分为哪几种几类型
  • 服务器几核几G几M是什么意思?如何选择?
  • 减少重复的请求之promise缓存池(构造器版) —— 缓存promise,多次promise等待并返回第一个promise的结果
  • 热门解压短视频素材下载网站推荐
  • unix中父进程如何获取子进程的终止状态
  • 第十七章:c语言内存函数