「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」
引入
浏览器是多进程的,它的内核是渲染进程,同个浏览器每打开一个页签就相当于新起一个渲染进程,渲染进程是多线程的,分别有:
GUI渲染线程: 渲染界面构建DOM树等JS引擎线程(JS内核): 负责处理脚本- 事件触发线程: 归属于浏览器,用于控制事件循环
- 定时器触发线程:
setInterval,setTimeout事件 - 异步
http请求线程:XHR请求 -> +线程 -> 检测状态变更(回调)
EventLoop
每个JS引擎线程都有一个独立的EventLoop(事件循环机制),事件循环是通过任务队列的机制来协调的
执行栈: 先进后出
任务队列: 先进先出
JS有同步任务和异步任务,同步任务在主线程即执行栈上执行;异步任务有了运行结果后,就在任务队列中新增一个事件。
当执行栈中的同步任务执行完毕后,系统读取任务队列,执行完任务队列中宏任务和微任务后,开始渲染页面。
宏任务和微任务
任务队列中的任务有两种类型,一种是宏任务(macroTask),一种是微任务(microTask)
宏任务包含了:
script- 定时器(
setTimeout,setInterval) I/OUI交互事件postMessageMessageChannelsetImmediate(Node.js环境)
微任务包含了:
Promise.then: 异步成功回调
Object.observe
MutationObserver
process.nextTick: 执行时间是在下一次事件循环之前
任务队列的执行顺序
任务队列的执行顺序是: 宏任务 -> 宏任务执行结束,检查是否有微任务 -> 有,执行所有微任务; -> 直到无其它微任务,浏览器渲染 -> 下一个宏任务