Skip to content

Commit 9451366

Browse files
committed
chore(ci): blog sync
1 parent 7785a54 commit 9451366

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

data/blog/post-23.mdx

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
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

Comments
 (0)