资讯专栏INFORMATION COLUMN

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

mgckid / 1770人阅读

摘要:为什么叫按照官网的解释在下次更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的。在下个事件循环执行时确实是最新的了,但是回调并没有在下个事件循环执行。

前言

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

什么时候开始本次Tick?

百度搜索event loops可以看到很多文章,但是看了很多文章都没让我知道或者作者没有去说明什么时候开始第一次tick,不过也幸运,还是有人skycity明确说出了,印象中之前掘金有篇文章我在评论里面也得到过答案,答案就是从全局script开始执行开始第一轮tick

什么时候结束本次Tick?

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

一次tick结束之后干嘛?

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

这个结论是我目前觉得正确的,希望有觉得不对的地方可以评论讨论下。

为什么叫next**?

按照官网的解释

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

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

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

根据上面的图可以看到最终回调有可能放入两个队列,那被执行的时机就有一下可能:
1:放入微任务队列,则在本轮tick执行
2:放入宏任务队列,则在下轮tick或者下下轮,或者下n轮
第二种为什么不确定呢?因为不知道放入队列时前面有几个任务在排队,可能以后n个计时器,而宏任务不像微任务一次全部执行完,宏任务是一个tick只执行一个任务,每个任务都在不同的tick,所以时机不定,但是肯定是在本轮tick之后

下面的代码我只走了支持Promsie的浏览器的过程,此时是在本轮tick执行
假设html中有这行代码

{{msg}}
我们在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

参考链接:

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

Javascript事件循环机制以及渲染引擎何时渲染UI

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96119.html

相关文章

  • 详细分析Vue.nextTick()实现

    摘要:因为平时使用都是传回调的,所以很好奇什么情况下会为,去翻看官方文档发现起新增如果没有提供回调且在支持的环境中,则返回一个。这就对了,函数体内最后的判断很明显就是这个意思没有回调支持。 Firstly, this paper is based on Vue 2.6.8刚开始接触Vue的时候,哇nextTick好强,咋就在这里面写就是dom更新之后,当时连什么macrotask、micro...

    DevYK 评论0 收藏0
  • Vue源码】VueDOM的异步更新策略以及nextTick机制

    摘要:本篇文章主要是对中的异步更新策略和机制的解析,需要读者有一定的使用经验并且熟悉掌握事件循环模型。这个结果足以说明中的更新并非同步。二是把回调函数放入一个队列,等待适当的时机执行。通过的主动来触发的事件,进而把回调函数作为参与事件循环。 本篇文章主要是对Vue中的DOM异步更新策略和nextTick机制的解析,需要读者有一定的Vue使用经验并且熟悉掌握JavaScript事件循环模型。 ...

    selfimpr 评论0 收藏0
  • Vue.js源码看异步更新DOM策略及nextTick

    摘要:我们发现默认是使用异步执行更新。优先使用,在不存在的情况下使用,这两个方法的回调函数都会在中执行,它们会比更早执行,所以优先使用。是最后的一种备选方案,它会将回调函数加入中,等到执行。 写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出。文章的原地址:https://github.com/ans...

    leo108 评论0 收藏0
  • Vue nextTick 机制

    摘要:而和的延迟明显是小于的。因为的事件机制是通过事件队列来调度执行,会等主进程执行空闲后进行调度,所以先回去等待所有的进程执行完成之后再去一次更新。因为首先触发了,导致触发了的,从而将更新操作进入的事件队列。这种情况会导致顺序成为了。 背景 我们先来看一段Vue的执行代码: export default { data () { return { msg: 0 ...

    Rindia 评论0 收藏0

发表评论

0条评论

mgckid

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<