前提概要
说到Vue中的$nextTick之前,先熟悉一下js中的宏任务与微任务,macroTask,microTask
(1)浏览器中,一个页面的js的执行依赖于一个主线程,但是用户点击的触发,ajax数据请求,io读取等依赖于其他相应的模块。
当主线程的执行堆栈执行完之后,会去读取任务队列,将任务(回调)放入执行堆栈执行,依次循环。任务队列里的任务由各种执行场景触发产生。
执行顺序:一整段script相当于宏任务,如果里面有其它setTimeout等宏任务触发,便会在其异步场景完成后(如定时完成)推入到宏任务队列。
有promise等微任务,则会将其推入到微任务队列,当前的宏任务执行完之后,会去读取微任务队列执行完,接下来进行读取宏任务队列。
从这种顺序看来,微任务往往执行于一次事件循环结束,而宏任务执行于下一次事件循环开始。所以promise的执行往往先于promise。
例:
let p = Promise.resolve();
p.then(()=> {
console.log(1);
})
setTimeout(() => {
console.log(2);
},0);
console.log(3);
// 打印顺序:3 1 2
首先vue中的this.$nextTick是在DOM更新循环之后执行延迟回调,vue是异步渲染页面的,所以有时候可能在页面没有完全渲染之前,就获取不到页面中最新的DOM,借助的就是js中的宏任务与微任务,实现执行回调的普通函数。
nextTick的实现
Mutation Observer 这个是H5中新增的API,这个接口能够监听DOM树上的更改
//MO会在监听到DOM发生变化时被调用 然后执行我们传入的回调函数
let MO = new MutationObserver(callback)