事件循环机制

154 阅读2分钟

事件循环机制

image.png

由来

每个渲染进程都有一个主线程,主线程需要处理DOM,又要计算样式,还要处理布局,同时还需要处理JS任务以及各种输入事件,需要保证这些任务有条不紊地执行,就需要一个机制来统筹调度,这个系统就是事件循环机制

消息队列

消息队列分为两种:普通队列和延时队列。 定时器因为是定时任务,设定的时间间隔没有到是不会执行,所以需要一个单独的模块,这个模块就是延时队列。

微任务

微任务的引入是为了使任务具有优先级,方便插队。

常见的宏任务

setTimeout
setInterval
setImmediate
用户交互事件(点击事件)
渲染事件
js脚本执行事件
网络请求
I/O

常见的微任务

promise
MulationObserver
process.nextTick
queueMicrotask

执行过程

1.执行同步代码 (碰到微任务加入当前宏任务的微任务队列,碰到宏任务加入消息队列)
2.执行完所有的同步代码后,且执行栈为空,判断是否有微任务执行(检查点)
3.执行完所有的微任务且微任务队列为空
4.渲染页面(是否需要)
5.执行下一个宏任务

实战练习

console.log('script start'); 
async function async1(){
    await async2()
    console.log('async1 end')
}
 async function async2(){
    console.log('asyn2');
}
async1()
setTimeout(function(){
    console.log('setTimeout');
},0)
new Promise(resolve=>{
    console.log('Promise');
    resolve()
})
.then(()=>{
    console.log('promise1');
})
.then(()=>{
    console.log('promise2');
})
console.log('script end');

答案分析

image.png
1.先执行同步代码 script start , async2 , Promise(promise的.then才属于微任务) , script end
2.检查点,检查微任务队列 [async1 end,promise1,promise2]
3.执行微任务队列 async1 end , promise1,promise2
4.无需渲染页面
5.执行下一个宏任务
延时队列中有个定时器到期了, setTimeout
(注意,async/await本质是promise和generator语法糖,从语法糖来看,generator中yield后接的promise会直接运行,next()放在.then中,.then又在微任务队列中,所以await除了后接的promise,余下的会进入微任务队列)