Vue nextTick

nextTick

    nextTick: 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

    nextTick 方法主要是使用了 宏任务 微任务 (可以看看我的另一篇文章 Event loop),定义了一个异步方法 timerFunc。多次调用 nextTick 会将方法存入队列 callbacks 中,通过这个异步方法清空当前队列。

nextTick

    声明了 timerFunc,优先检测是否支持 Promise,如果不支持在检测是否支持 MutationObserver,失败的话再检查 setImmediate,如果还不支持,最后只能是 setTimeout,可见  setTimeout 的性能是最差的。

    再看对外暴露的 nextTick 函数,在 Vue 响应式(链接) 中 最后执行了  nextTick(flushSchedulerQueue),把传入的回调函数 cb 压入 callbacks 数组,然后 在下⼀个 tick 执行  flushCallbacks , flushCallbacks 中 对 callbacks 遍历,然后执行相应的回调函数。

    这里使用  callbacks 而不是直接在 nextTick 中执行回调函数的原因是保证在同⼀个 tick 内多次执行  nextTick ,不会开启多个异步任务,而把这些异步任务都压成⼀个同步任务,在下⼀个 tick 执行完毕。

示例

    比如 this.onOfData = XX 和 this.$nextTick(()=>{}),这两个任务,首先会将 this.onOfData 的改变加入到  callbacks  队列中,此时 会执行

    if (!pending) {

      pending = true;

      timerFunc();

  }

    timerFunc()执行, 假设我们支持的是 Promise,那么就会 执行  Promise.resolve().then(flushCallbacks);

   但是 同步任务 还没执行完,也就是  this.$nextTick(()=>{}) 这个同步任务没执行,所以优先执行这个,加入到队列  callbacks , 此时pending 为 true , 所以就不会 走 if 判断 让 if 语句的逻辑只执行一次;

接着同步任务都执行完成,接着就 执行 微任务  flushCallbacks(), 会执行完 callbacks  中的所有任务,此时 callbacks  有两个任务,一个是 data 的改变, 一个是 $nextTick。


    nextTick 函数最后还有⼀段逻辑:

    if (!cb && typeof Promise !== 'undefined')

    { return new Promise(resolve => { _resolve = resolve }) }

     这是当 nextTick 不传 cb 参数的时候,提供⼀个 Promise 化的调用,⽐如:

    nextTick().then(() => {}) 

    callbacks.push 中的函数就会走else 逻辑 ()=>  _resolve(ctx);

    当 _resolve 函数执行,也就会直接 resolve(),就会跳到 then 的逻辑中。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容