Skip to content

Event Loop

事件循环

🔥事件队列 异步 进程 线程

CPU、进程、线程之间的关系

进程是 cpu 资源分配的最小单元(是能拥有资源和独立运行的最小单位)

线程是 cpu 调度的最小单位(线程是建立在进程的基础上的一次程序运行单位,一个进程中可以有多个线程)

不同进程之间也可以通信,代价较大

单线程多线程,都是指在一个进程内的单和多

浏览器是多进程的

浏览器是多进程的

每一个 tab 页,就是一个独立的进程

浏览器包含了哪些进程

主进程

  • 协调控制其他子进程(创建、销毁)

  • 浏览器界面显示,用户交互,前进、后退、收藏

  • 将渲染进程得到的内存中的 bitmap,绘制到用户界面上

  • 处理不可见操作,网络操作,文件访问

第三方插件进程

每个插件一个进程,使用的时候,进程被创建

GPU 进程

用于 3D 绘制等

渲染进程(浏览器内核)

  • 负责页面渲染,脚本执行,事件处理等

  • 每个 tab 页一个渲染进程

浏览器内核(渲染进程)

GUI 渲染进程

  • 负责渲染页面,布局和绘制

  • 页面需要重绘和回流时,该线程就会执行

  • 与 js 引擎互斥,防止渲染结果不可预期

JS 引擎线程

  • 负责处理解析和执行 JavaScript 脚本程序

  • 只有一个 JS 引擎线程(单线程)

  • 与 GUI 渲染线程互斥,防止渲染结果不可预期

事件触发线程

  • 用来控制事件循环(鼠标点击,setTimeout,ajax)

  • 当事件满足触发条件时,将事件放入到 JS 引擎所在的执行队列中

定时触发器线程

  • setInterval 与 setTimeout 所在的线程

  • 定时任务并不是由 JS 引擎计时的,是由定时触发线程来计时的

  • 计时完毕后,通知事件触发线程

异步 http 请求线程

  • 浏览器有一个单独的线程用于处理 AJAX 请求

  • 当请求完成时,若有回调函数,通知时间触发线程

JavaScript 单线程?

多线程需要加锁,同时操作DOM,在多线程不加锁的情况下,最终会导致DOM渲染的结果不可预期

GUI 渲染线程与 JS 引擎线程互斥?

当JS引擎线程执行时,GUI渲染线程会被挂起,GUI更新则会被保存在一个队列中等待JS引擎线程空闲时立即被执行

Event Loop GO

  • 同步任务和异步任务

  • 同步任务在 js 引擎线程上执行,形成一个执行栈

  • 事件触发线程管理一个任务队列,异步任务触发条件达成,将回调事件放到任务队列中

  • 执行栈中所有同步任务执行完毕,js 引擎线程空闲,系统会读取

  • 宏任务 --> 事件队列(循环)

  • 微任务 --> 微任务队列

宏任务完成立即执行当前一轮的微任务

  • 执行一个宏任务(栈中没有从事件队列中获取)

  • 执行过程中如果遇到微任务,添加到微任务队列

  • 宏任务执行完毕后,立即执行当前微任务队列的所有微任务

  • 宏任务执行完毕,开始检查渲染,然后 GUI 线程接管渲染

  • 渲染完毕后,js 线程继续接管,开始下一个宏任务(事件队列)

Released under the MIT License.