渲染进程中的主线程是一个单线程,同一时间只能执行一个任务,所以渲染进程中维护了一个消息队列,用于存放要执行的任务,后来的任务总是被添加到队列的尾部等待执行,所以后面的任务需要等待一段事件才会执行,但是,有些任务的优先级又是比较高的,要优先执行这些任务,js引擎就要停止其他任务的执行,转而执行优先级高的任务,这样会阻塞其他任务,所以js引进了事件循环。
本文主要讲事件循环中的宏任务和微任务。在了解宏任务和微任务之前先看一下同步任务和异步任务。
一、同步任务
同步任务就是执行时,执行被放进消息队列中,等待执行的任务。
例如:
console.log('test');
let name = 'test';
这都是同步任务,执行了就立即出结果了。
二、异步任务
异步任务就是执行时,将回调放进对应的线程队列中,等待触发条件被触发,将任务放进消息队列中等待执行。
例如:
window.addEventListener('click', function (e) =>{
console.log(e.target.value);
})
这就是异步任务,当js引擎执行到这段代码时,会将回调函数放进事件触发线程的队列中,当页面有事件点击时,会将该任务从事件触发线程的队列中取出,放在消息队列中等待执行。
三、宏任务
为了让优先级比较高的任务,比如造成页面渲染的任务及时执行,并且不阻塞之后的任务,js将任务分为宏任务,宏任务就是消息队列中的任务。
分类有:
-
js整体代码
-
setTimeout
-
setInterval
-
I/O
-
UI交互事件
-
postMessage
-
setImmediate
四、微任务
每一个宏任务都有一个队列来保存在这个宏任务执行期间产生的微任务,在这个宏任务执行完,要结束时会将其微任务中队列中的任务执行完,然后才会渲染。
微任务有:
-
Promise.then以及其相关的语法糖
-
Object.observe
-
MutationObserve
-
process.nextTick
注意:
宏 ----> 微 ---->渲染 ----> 宏 ----> 微 ----> 渲染.......