|  | 
|  | 1 | +--- | 
|  | 2 | +title: JS 中的事件循环 - 懂前端的都知道这里的门道有多深! | 
|  | 3 | +date: 2024-11-01T14:12:55Z | 
|  | 4 | +slug: post-23 | 
|  | 5 | +author: coderPerseus:https://github.com/coderPerseus | 
|  | 6 | +tags: [] | 
|  | 7 | +--- | 
|  | 8 | + | 
|  | 9 | +有人说:如果你不会时间循环,那么你就根本不会前端。听完我就来气了,我是不懂事件循环,但也完成了那么多需求,写了那么多代码,怎么我就不懂前端了呢?不行,我必须要看看这个事件循环到底是什么东西,到时候好和提出这个观点的人理论一番。下面跟我来看看事件循环到底是什么吧! | 
|  | 10 | + | 
|  | 11 | +## 什么是事件循环 ? | 
|  | 12 | + | 
|  | 13 | +事件循环是游览器渲染进程的渲染主线程的工作方式。看到这个描述的我是一脸懵的,我就知道事情不简单,没办法只能拆解这句话不懂的地方逐个击破了,让我们先来看看什么是 渲染进程 吧 ~ | 
|  | 14 | + | 
|  | 15 | +## 渲染进程 | 
|  | 16 | + | 
|  | 17 | +> 小知识:游览器是多进程多线程的。很好理解,当你打开一个标签页面开始,其他标签页面不受影响,这就是说明一个标签页面就是一个进程,多线程就更好理解,一个标签进程下面就会有网络进程,渲染进程等等 | 
|  | 18 | +
 | 
|  | 19 | +说渲染进程之前可能有些人都不知道进程是什么!例如我,通过学习理解,我们可以简单理解进程为:为「程序运行」分配的「内存空间」。打个比方,阿牛要去公司上班,公司需要为阿牛分配工位,工牌,电脑等设施和工具。这里的阿牛就是程序,它需要的设备就是进程。那在游览器中程序工作也就需要为程序分配一个单独的空间,下面我们继续了解一下进程的特点, | 
|  | 20 | +- 每个程序(应用)至少有一个进程 | 
|  | 21 | +- 进程可以有多个,进程之前相互独立,如果需要通信需要双方同意 | 
|  | 22 | +- 每个进程是隔离的,一个进程崩溃了,不会影响其他的进程 | 
|  | 23 | + | 
|  | 24 | +通过了解进程的特点,我们类比阿牛,就能更加深刻理解进程。那渲染进程其实就是进程的一个实例,它继承进程的所有特点,下面我们看一下游览器中的三个重要进程: | 
|  | 25 | +1)游览器进程:它负责 chrome 游览器的界面(是全局的界面)显示,用户交互,子进程管理(最开始游览器启动只有这一个进程,但是它会启动其他进程) | 
|  | 26 | +2)网络进程:加载网络资源 | 
|  | 27 | +3)渲染进程:开启一个渲染主线程,主线程负责执行 HTML、CSS、JS | 
|  | 28 | + | 
|  | 29 | +## 渲染主线程 | 
|  | 30 | +渲染进程默认就是生成一个渲染主线程。肯定有小伙伴会不知道什么是线程?例如我,线程简单理解为:运行程序代码的「人」就是「线程」。一个进程至少会有一个线程(主线程,也就是跟随进程启动的时候产生的线程),这里是因为内存空间是宝贵的,如果没有线程,内存空间(也就是进程)就会被释放。 | 
|  | 31 | + | 
|  | 32 | +进程和线程的关系:一个进程可以有多个线程,线程运行开进程中 | 
|  | 33 | + | 
|  | 34 | +## 为什么渲染进程只有一个主线程 ? 渲染主线程要做哪些事情? | 
|  | 35 | + | 
|  | 36 | +下面这些都是渲染主线程的工作 | 
|  | 37 | +- 解析 HTML | 
|  | 38 | +- 解析 CSS | 
|  | 39 | +- 计算样式 | 
|  | 40 | +- 布局 | 
|  | 41 | +- 处理图像 | 
|  | 42 | +- 每秒把页面画 60 次 | 
|  | 43 | +- 执行全局 JS 代码 | 
|  | 44 | +- 执行事件处理函数 | 
|  | 45 | +- 执行计时器的回调函数 | 
|  | 46 | +- 。。。。 | 
|  | 47 | + | 
|  | 48 | +那为什么渲染进程不适用多个线程来处理这么多的事情?而是全部交给渲染主线程?其主要原因: | 
|  | 49 | +1. JavaScript是单线程,如果开启多个线程,需要处理复杂的线程同步; | 
|  | 50 | +2. 还可能出现多个线程同时操作 DOM 导致的竞态条件 | 
|  | 51 | +3. 一致性问题,如:dom 操作循序性和原子性、JavaScript 代码执行顺序 | 
|  | 52 | + | 
|  | 53 | +做前端的都知道 JavaScript 是单线程的,那为什么单线程在处理同步,异步非常复杂的程序时,页面依然不卡呢?继续看 | 
|  | 54 | + | 
|  | 55 | +## 任务调度 - 插队 | 
|  | 56 | +通过其他线程来执行一些程序,生成任务,然后任务会进入消息队列(message  queue),然后渲染主线程会把消息队列中的任务依次进行执行 | 
|  | 57 | + | 
|  | 58 | +最开始,渲染主线程进入无限循环 | 
|  | 59 | + | 
|  | 60 | +每次循环都会查看是否有任务,有任务会执行任务,没有任务进入休眠 | 
|  | 61 | + | 
|  | 62 | +其他线程可以随时向消息队列添加任务(加入到队列末尾),如果新任务加入时渲染主线程在休眠,就会被唤醒 | 
|  | 63 | + | 
|  | 64 | + | 
|  | 65 | +## 为什么要学习事件循环? | 
|  | 66 | + | 
|  | 67 | +那到这里,学习事件循环的原因也很好理解了,事件循环是渲染主线程的工作原理,前端的所有工作也又都在渲染主线程 | 
|  | 68 | + | 
|  | 69 | + | 
|  | 70 | + | 
|  | 71 | +--- | 
|  | 72 | +此文自动发布于:<a href="https://github.com/coderPerseus/blog/issues/23" target="_blank">github issues</a> | 
0 commit comments