关于vue中next和Tick(nextTick)的一点理解

前言

在这以前我是没有怎么看过vue源码的,可是看了源码后又产生了一些疑问,若是不看源码我还真没有任何疑问的去用nextTick,由于我只知道我想获取更新后的dom我就在里面写回调,只管写准没错,有天好奇调试了下代码就发现了一些疑问....javascript

何时开始本次Tick?

百度搜索event loops能够看到不少文章,可是看了不少文章都没让我知道或者做者没有去说明何时开始第一次tick,不过也幸运,仍是有人skycity明确说出了,印象中以前掘金有篇文章我在评论里面也获得过答案,答案就是从全局script开始执行开始第一轮tickhtml

何时结束本次Tick?

这个也是我根据搜索资料得出结论,当GUI 渲染完后本轮Tick结束,可是在开始渲染以前js 引擎会执行完全部的微任务队列,新的叫法是jobs,宏任务叫tasksvue

一次tick结束以后干吗?

继续查找事件任务队列中是否有tasks,若是没有就静静等待非空,若是有就继续开始第二轮tick,取出tasks执行 我画了个图能够表示下这个过程java

这个结论是我目前以为正确的,但愿有以为不对的地方能够评论讨论下。

为何叫next**?

按照官网的解释git

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

我我的是并不理解这个下次dom更新循环是指的什么?是跟event loop这个事件循环一个意思吗?本次dom更新循环是何时开始?何时结束?但愿有人知道的解释下。我以为执行回调的时机是在下个tick以前执行的,segmentfault

2018.7.21更新:根绝 SHERlocked93 大佬的文章参考以及他的回答,nextTick的回调执行时机实际上是不肯定的,看下面这个图:浏览器

根据上面的图能够看到最终回调有可能放入两个队列,那被执行的时机就有一下可能:

1:放入微任务队列,则在本轮tick执行dom

2:放入宏任务队列,则在下轮tick或者下下轮,或者下n轮 第二种为何不肯定呢?由于不知道放入队列时前面有几个任务在排队,可能之后n个计时器,而宏任务不像微任务一次所有执行完,宏任务是一个tick只执行一个任务,每一个任务都在不一样的tick,因此时机不定,可是确定是在本轮tick以后异步

下面的代码我只走了支持Promsie的浏览器的过程,此时是在本轮tick执行 假设html中有这行代码 <div ref="msg">{{msg}}</div> 咱们在mounted里面执行

this.msg = 'hello';
this.$nextTick(()=>{
    console.log(this.$refs.msg.innerHTML)
})
复制代码

上述代码在vue里面的大体以下执行流程以下

经过上面的流程分析,nextTick里面的回调是在当前时间循环内执行的,并无在下个事件循环执行。so,在下个事件循环执行时dom确实是最新的了,可是回调并无在下个事件循环执行。

总结

1.nextTick里面的回调是在本轮tick循环中执行的 nextTick里面的回调是在本轮tick或者下n轮tick中执行的(n=1,2,3...)

2.全部的微任务会在本轮tick中所有执行完

3.任何一个宏任务也就是tasks都不在一个tick中执行,而是在不一样的tick

4.强烈推荐你们去看下这两篇文章,写的很详细 :

Vue源码阅读 - 批量异步更新与nextTick原理

2018.7.26更新:补一篇文章,5星推荐这个

Vue源码详解之nextTick:MutationObserver只是浮云,microtask才是核心!

参考连接:

理解javascript中的事件循环(EventLoop)

Javascript事件循环机制以及渲染引擎什么时候渲染UI

从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理

相关文章
相关标签/搜索