!!! 理解学习,有问题/补充欢迎指出,随时改正 !!!
事件循环
- 一、进程与线程
- 二、浏览器进程模型
- 三、为什么会存在事件循环机制
- 四、事件循环机制
- 五、代码场景模拟事件循环机制
- 六、练习题(明天补充...)
一、进程与线程
- 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位,是操作系统结构的基础。简单的理解:操作系统分配给程序执行的一块独立的内存空间,进程间通讯相互独立
- 线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。简单理解:进程启动时会启动一个主线程用于程序运行,进程可以同时开启多个线程,主线程关闭后进程会被杀死释放内存
二、浏览器进程模型
- 浏览器内部十分复杂,启动浏览器打开浏览器任务管理器可以发现,浏览器是多进程的应用程序。举例但不限于:浏览器进程,网络进程,渲染进程,存储进程,音频进程…
- 浏览器进程:主要职责:浏览器“外壳”功能控制,协调各进程的指挥中心
- 网络进程:加载网络资源,网络请求的处理是涉及多个进程协作,虽然有专门的网络进程,但浏览器进程和渲染进程也会参与其中
- 渲染进程:!!!单线程,一个标签页代表着一个渲染进程,用于处理html/css/js渲染界面
三、为什么会存在事件循环机制
这里我更倾向理解成:浏览器对于执行任务顺序的分配机制,保证资源的最优占用
- 任务是在渲染线程中进行处理,由于渲染线程为单一线程,如果所有任务均需同步按序执行,且存在需要等待资源/时间…的任务会导致渲染进程阻塞
- 阻塞会导致渲染线程卡死,交互无响应,资源浪费等问题,为了解决任务性质上的阻塞问题,实现了事件循环
四、事件循环机制
- Chrome源码中,会开启一个不会结束的for循环,每次循环从消息队列去除第一个任务执行,而其他线程只需在合适的时候将任务加入到队列末尾 – 来自大佬的解读
- 现针对于队列的命名方式有不同看法,个人看法:无论是宏/微任务还是微/延时/交互队列。都可以理解为渲染进程是根据任务执行队列的权重来排序执行。一类任务必须在同一队列,一个队列可以有不同任务类型
五、代码场景模拟事件循环机制
方便同一理解,这里就采用老朋友promise(微任务/微队列)和setTimeout(宏任务/延时队列)来模拟
Promise.resolve().then(() => {console.log(2);setTimeout(() => { console.log(5)},0)})console.log(1);setTimeout(() => {console.log(3);Promise.resolve().then(() => {console.log(4);})}, 0);//log 1,2,3,4,5
//第一次循环
/*
微任务队列:[{console.log(2);setTimeout(() => { console.log(5)},0)
}]
同步任务:console.log(1); 进入渲染主线程
其它队列:[{console.log(3);Promise.resolve().then(() => {console.log(4);})
}]打印:1
*/
//第二次循环
/*
同步任务执行结束,开始读取微任务队列
同步任务:console.log(2) // 渲染线程执行任务后发现,setTimeout产生新任务到其它队列(理解为:宏任务/延时队列)
其它队列:[{console.log(3);Promise.resolve().then(() => {console.log(4);})},{setTimeout(() => { console.log(5)},0)}
]打印:1,2
*/
//第三次循环
/*
当前状态同步任务和微任务均无排队,开始执行其它队列(理解为:宏任务/延时队列)
同步任务:console.log(3); // 渲染线程执行任务后发现,产生新的微任务,放入微任务队列
微任务队列:[{Promise.resolve().then(() => {console.log(4);})
}]
其它队列:[{setTimeout(() => { console.log(5)},0)
}]打印:1,2,3
*/
//第四次循环
/*
渲染线程空闲,优先读取微任务队列执行
同步任务:console.log(4); // 执行后,此时同步任务与微任务队列都执行结束
其它队列:[{setTimeout(() => { console.log(5)},0)
}]打印:1,2,3,4
*/
//第五次循环
/*此时渲染主线程和微任务队列都执行完毕,仅剩其它队列(理解为:宏任务/延时队列)存在任务执行
同步任务:console.log(5);打印:1,2,3,4,5
*/