首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Vue.js技术揭秘-nextTick

nextTick

是 Vue 的一个核心实现,在介绍 Vue 的 nextTick 之前,为了方便大家理解,先简单介绍一下 JS 的运行机制。

JS 运行机制

JS 执行是单线程的,它是基于事件循环的。事件循环大致分为以下几个步骤:

所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

主线程不断重复上面的第三步。

主线程的执行过程就是一个 tick,而所有的异步结果都是通过 “任务队列” 来调度。消息队列中存放的是一个个的任务(task)。规范中规定 task 分为两大类,分别是 macro task 和 micro task,并且每个 macro task 结束后,都要清空所有的 micro task。

简单通过一段代码演示他们的执行顺序:

在浏览器环境中:

常见的 macro task 有 setTimeout、MessageChannel、postMessage、setImmediate;

常见的 micro task 有 MutationObsever 和 Promise.then。

Vue 的实现

在 Vue 源码 2.5+ 后, 的实现单独有一个 JS 文件来维护它,它的源码并不多,总共也就 100 多行。接下来我们来看一下它的实现,在 中:

申明了 和 2 个变量,它们分别对应的是 micro task 的函数和 macro task 的函数。对于 macro task 的实现,优先检测是否支持原生 ,这是一个高版本 IE 和 Edge 才支持的特性,不支持的话再去检测是否支持原生的 ,如果也不支持的话就会降级为 ;而对于 micro task 的实现,则检测浏览器是否原生支持 Promise,不支持的话直接指向 macro task 的实现。

对外暴露了 2 个函数,先来看 。它的逻辑也很简单,把传入的回调函数 压入 数组,最后一次性地根据 条件执行 或者是 ,而它们都会在下一个 tick 执行 , 的逻辑非常简单,对 遍历,然后执行相应的回调函数。

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

函数最后还有一段逻辑:

这是当 不传 参数的时候,提供一个 Promise 化的调用,比如:

当 函数执行,就会跳到 的逻辑中。

还对外暴露了 函数,它是对函数做一层包装,确保函数执行过程中对数据任意的修改,触发变化执行 的时候强制走 。比如对于一些 DOM 交互事件,如 绑定的事件回调函数的处理,会强制走 macro task。

总结

nextTick 接收一个回调函数作为参数,并将这个回调函数延迟到DOM更新后才执行;

使用场景:想要操作基于最新数据生成的DOM时,就将这个操作放在 nextTick 的回调中。

例如:从服务端接口去获取数据时,数据改变了,我们的某些方法依赖了数据变化后的 DOM 变化,就必须在 后执行。比如下面例子:

Vue.js 提供了 2 种调用 的方式,一种是全局 API ,一种是实例上的方法 ,无论我们使用哪一种,最后都是调用 中实现的 方法。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20230129A011JD00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券