<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vue 同步 $nextTick setTimeout 执行的顺序</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
<button @click="clickMe" id="btn">{{msg}}</button>
<div>
事件循坏vent Loop中,每一次循环称为tick,每一次tick的任务如下:
执行栈选择最先进入队列的宏任务(一般都是script),执行其同步代码直至结束;
检查是否存在微任务,有则会执行至微任务队列为空;
如有必要会渲染页面;
开始下一轮tick,执行宏任务中的异步代码(setTimeout的回调等)。
<br>
宏任务与微任务
宏任务(macrotask)
宿主(Node、浏览器)发起的任务;
在ES6规范中,将其称为task;
script、setTimeout、setInterval、I/O、UI rendering、postMessage、MessageChannel、setImmediate
微任务(microtask)
JS引擎发起的任务;
在ES6规范中,将其称为jobs;
Promise、MutaionObserver、process.nextTick
</div>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
msg: '点击按钮判断控制台打印的内容'
},
methods: {
clickMe() {
this.msg = '执行顺序 同步 => promise => setTimeout'
console.log('start')
setTimeout(() => {
console.log('timeout')
}, 0)
this.$nextTick(() => {
console.log('nextTick')
this.$nextTick(() => {console.log('nextTick2')})
setTimeout(() => {
console.log('timeout2')
}, 0)
})
console.log('end')
}
// 先执行同步在执行异步 => 执行$nextTick返回promise,执行timeout (promise比timeout快)
// 事件循环机制: 同步 => 微任务 => 渲染页面 => 开始下一轮,执行宏任务中的异步代码(setTimeout的回调等)
// 为什么promise比timeout快 https://blog.csdn.net/weixin_34365635/article/details/91421326
// 1. start
// 2. end
// 3. nextTick
// 4. nextTick2
// 5.nextTick2
// 6.timeout
// 7.timeout2
}
})
</script>
</body>
</html>