9、谈一谈 nextTick 的原理

208 阅读1分钟

由于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)