关于Vue的nexkTick

看了看nextTick的源码,内部好像是优先使用Promise实现

if (typeof Promise !== 'undefined' && isNative(Promise)) {
  const p = Promise.resolve()
  timerFunc = () => {
    p.then(flushCallbacks)
    
    if (isIOS) setTimeout(noop)
  }
} else if ....

但Promise的回调作为微任务,应该是在本次事件循环结束前执行的,也就是在DOM更新前执行。

但实际的情况是,nextTick的回调确实会在DOM更新后执行,是我哪里的理解错误的呢~

阅读 2.8k
2 个回答

html规范
执行 UI render 操作:
判断 document 在此时间点渲染是否会『获益』。浏览器只需保证 60Hz 的刷新率即可(在机器负荷重时还会降低刷新率),若 eventloop 频率过高,即使渲染了浏览器也无法及时展示。不是每轮 eventloop 都会执行 UI Render。

所以准确的来说UI rendering是事件循环里面的一个和微任务平行的操作步骤,根据相关机制来执行的,而不是单纯把它当作一个宏任务。

第一次回答感觉太随便了良心过不去,删掉重新来一次。

首先表明不是为了回答而回答的,同时也是为了给出自己的观点,有错的也可以及时被大家指正。

image.png

该图是我在 performance 中,截取的一个关于 click event 中调用 this.$nextTick().then(func...)main 部分。

经过多次尝试,图中的 Run Microtasks 代表着开始执行微任务(也就是 nextTick)。其中黄色部分是 nextTick 函数内部动作,右侧倒数第二列的浅绿色 anonymouse 是我们传递的回调函数。

问题是为什么在 nextTick 之前无法获取到最新的 DOM 内容,而在 nextTikc.then 之后却可以?

重点就是中间的黄色部分。

可以看到其中层层深入的在 update Component、VNode、DOMProps、DOMAttrs...,然后当一切 update 结束之后,开始执行我们传递给 nextTick().then(func...) 的回调函数。

这也就解释了为什么在 then 里面就可以获取到最新的 DOM 内容了。

本回答完全基于推测,没有任何明确证据,仅做参考!

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题