前言
最近看到w3c标准里对 Event Loop 的说明已经不存在宏任务(宏队列)的说法了所以记录下
浏览器的主要进程有:
-
浏览器主进程(Browser Process) :
- 负责管理浏览器界面、标签页、窗口等
- 处理网络请求、文件访问等底层操作
- 协调其他进程的工作
-
网络进程(Network Process) :
- 负责加载网络资源
- 处理网络请求(HTTP、HTTPS等)
- 管理缓存、Cookie等网络相关数据
-
渲染进程(Renderer Process) :
- 每个标签页通常有一个独立的渲染进程
- 负责解析和渲染网页内容(HTML、CSS、JavaScript)
- 主线程每秒渲染页面 60 次,每次渲染的时间间隔约为 16.67 毫秒
- 通过沙箱机制运行,确保安全性
- Event Loop 是渲染进程中 JavaScript 引擎(如 V8)的一部分,用于处理异步任务
什么是 Event Loop
根据html标准总结来说是:为了确保 渲染主线程( JavaScript 的单线程模型)能够高效地处理异步操作(如 页面渲染、定时器、网络请求、事件回调等),而不会阻塞主线程的任务调度机制
任务队列/消息队列
- 事件循环具有一个或多个任务队列。一个 Task Queue 是一组任务
- 任务都有一个类型,同一类型的任务必须在一个队列
- 每个事件循环都有一个微任务队列
常用队列:
- 微队列:优先级【最高】,存放需要快速执行的任务
- 添加主要方式:
Promise回调、queueMicrotask、MutationObserver等
- 添加主要方式:
- 交互队列:优先级【高】,存放用户操作之后产生的事件处理任务
- 延时队列:优先级【中】,存放计时器
示例
<div id="app" style="color:red">事件循环示例点击'开始按钮后'再点击‘添加队列’查看控制台输出 </div><br/>
<button id="start" type="button" onclick="onStartClick()">开始</button>
<button id="btn" type="button">添加队列</button>
/***
* 事件循环示例
*
*/
function log(...args){
return console.log(new Date().toJSON(),args)
}
function delay(duration){
const now = new Date().valueOf();
log('start delay')
while((new Date().valueOf() - now)<=duration){
}
log('end delay')
}
function addDlay(){
console.log("添加到延时队列执行")
setTimeout(function(){
log("延时队列执行")
},0)
}
function addMicrotask(){
log("添加到微任务队列")
new Promise((resolve)=>{
log('微任务执行')
}).then()
}
function onStartClick(){
log("onStartClick in")
addDlay();
addMicrotask();
addBtnClick();
delay(3000)
}
function addBtnClick(){
const btn = document.getElementById('btn');
log("添加交互队列");
function e(){
log("交互队列执行")
btn.removeEventListener('click',e);
}
btn.addEventListener('click',e)
}