在一輪事件循環(huán)中:
執(zhí)行宏任務(wù) => 執(zhí)行微任務(wù) => 執(zhí)行 UI Rendering ... 下一輪事件循環(huán)。。。
微任務(wù)(Promise.then)實(shí)現(xiàn): js 操作dom 之后,微任務(wù)開(kāi)始執(zhí)行,此時(shí) UI還沒(méi)渲染,但是沒(méi)有關(guān)系,它遲早要渲染的,因?yàn)槲覀円呀?jīng)更新 dom 了,此時(shí)獲取 dom 的數(shù)據(jù)也是更新后的數(shù)據(jù)。
宏任務(wù)(setTimeout)實(shí)現(xiàn):創(chuàng)建一個(gè)新的 task 并加入事件隊(duì)列的末尾,操作 dom 的任務(wù)和到該宏任務(wù)直接可能間隔了多個(gè)宏任務(wù)。
區(qū)別:宏任務(wù)執(zhí)行完畢之后會(huì)執(zhí)行所有微任務(wù), 微任務(wù)在與更新數(shù)據(jù)的操作的同一輪事件循環(huán)中執(zhí)行,而宏任務(wù)則是再下一輪事件循環(huán)執(zhí)行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.a {
background-color: coral;
height: 100px;
}
</style>
<script src="vue.min.js"></script>
</head>
<body>
<div id="app">
<div class="a" @click="change" :style="{ width: w + 'px' }">
</div>
</div>
<script>
let app = new Vue({
el: '#app',
data: {
w: 100
},
methods: {
change() {
this.w += 100
let method = 1
if (method == 1) {
// 微任務(wù)形式
Promise.resolve().then(() => {
alert('頁(yè)面更新了么')
console.log(document.querySelector('.a').clientWidth)
})
} else if (method == 2) {
// 宏任務(wù)形式
setTimeout(() => {
alert('頁(yè)面更新了么')
console.log(document.querySelector('.a').clientWidth)
})
}
}
}
})
</script>
</body>
</html>