由于dom的更新会触发页面的回流或者是重绘是十分耗费性能的;
所以Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是异步执行 DOM 更新的
当触发了setter函数,vue会将这个watcher对象push到一个队列中,并且同一个watcher多次触发只会被push一次;
利用事件循环机制,让这个队列的执行是异步的微任务或者是宏任务,在一次事件循环的末尾执行即可;
异步优先采用微任务microTask(Promise),如果浏览器不支持则用宏任务macroTask(优先setImmediate ,不支持则用settimeout(()=> {}, 0))
源码:
var queue = []
var pending = false
function executeCallbacks() {
queue.forEach(item => {
item()
pending = false
})
}
function nexttick(fun) {
queue.push(fun)
if (pending) return
pending = true
Promise.resolve().then(executeCallbacks)
}
function render() {
console.log('render')
}
nexttick(render)
nexttick(render)
console.log(111)