# 线程和进程
初学 JS 的时候各种资料都会介绍 JS 是单线程执行的。那线程和进程都是什么?
# 概念
进程是 CPU 资源分配的最小单位 线程是 CPU 调度的最小单位
这两句话比较难理解,举个例子:
将进程看做是工厂,线程看做是工人。
一个工厂可以有多个工人,也就是说一个进程可以由多个线程组成,线程是一个进程中代码不同的执行线路
工厂的空间是工人们共享的,即一个进程的内存空间是它的所有线程共享的
多个工厂独立存在,即进程之间是独立的,互不影响
以 Chrome 为例,每打开一个 Tab 页,就是创建了一个进程,一个进程可以有多个线程(下文会详细介绍),比如渲染线程、js 线程等;每发送一个请求,就是创建了一个线程,请求结束后该线程就会被销毁。
# 浏览器内核
浏览器内核是多线程,一个浏览器通常由一下常驻线程组成:
- GUI 渲染线程
- Javascript 引擎线程
- 定时器触发线程
- 事件触发线程
- 异步 http 请求线程
# 1. GUI 渲染线程
- 负责页面的渲染,解析 HTML、CSS,构建布局树(Layout tree)并绘制。
- 负责界面需要重绘或者回流
- 负责与 JS 引擎线程交互,当 JS 引擎线程,GUI 渲染线程会被挂起
# 2. Javascript 引擎线程
- 负责执行 js 脚本
- 负责与 GUI 交互
# 3. 定时器触发线程
- 负责执行异步定时器的线程,如: setTimeout,setInterval
- 主线程依次执行代码时,遇到定时器,会将定时器交给该线程处理,当计数完毕后,事件触发线程会将计数完毕后的事件加入到任务队列的尾部,等待 JS 引擎线程执行
# 4. 事件触发线程
- 负责将准备好的事件交给 JS 引擎线程执行,比如 setTimeout 定时器计数结束,http 等异步请求成功并触发回调函数,或者用户触发点击事件时,该线程会将整装待发的事件依次加入到任务队列的队尾,等待 JS 引擎线程的执行
# 5. 异步 http 请求线程
- 负责执行异步请求一类的函数的线程,如:Promise,fetch,ajax 等
- 主线程依次执行代码时,遇到异步请求,会将函数交给该线程处理,当监听到状态码变更,如果有回调函数,事件触发线程会将回调函数加入到任务队列的尾部,等待 JS 引擎线程执行
事件循环 →