简单理解Vue中的nextTick方法(3)

首先,先了解nextTick中定义的三个重要变量。

  1. callbacks:用来存储所有需要执行的回调函数
  2. pending:用来标志是否正在执行回调函数
  3. timerFunc:用来触发执行回调函数

接下来,了解nextTickHandler()函数。

function nextTickHandler () {
  pending = false
  const copies = callbacks.slice(0)
  callbacks.length = 0
  for (let i = 0; i < copies.length; i++) {
   copies[i]()
  }
 }

这个函数用来执行callbacks里存储的所有回调函数。

接下来是将触发方式赋值给timerFunc。

先判断是否原生支持promise,如果支持,则利用promise来触发执行回调函数;

否则,如果支持MutationObserver,则实例化一个观察者对象,观察文本节点发生变化时,触发执行所有回调函数。

如果都不支持,则利用setTimeout设置延时为0。

最后是queueNextTick函数。因为nextTick是一个即时函数,所以queueNextTick函数是返回的函数,接受用户传入的参数,用来往callbacks里存入回调函数。

上图是整个执行流程,关键在于timeFunc(),该函数起到延迟执行的作用。

从上面的介绍,可以得知timeFunc()一共有三种实现方式。

  1. Promise
  2. MutationObserver
  3. setTimeout

其中Promise和setTimeout很好理解,是一个异步任务,会在同步任务以及更新DOM的异步任务之后回调具体函数。

下面着重介绍一下MutationObserver。

MutationObserver是HTML5中的新API,是个用来监视DOM变动的接口。他能监听一个DOM对象上发生的子节点删除、属性修改、文本内容修改等等。

调用过程很简单,但是有点不太寻常:你需要先给他绑回调:

var mo = new MutationObserver(callback)

通过给MutationObserver的构造函数传入一个回调,能得到一个MutationObserver实例,这个回调就会在MutationObserver实例监听到变动时触发。

这个时候你只是给MutationObserver实例绑定好了回调,他具体监听哪个DOM、监听节点删除还是监听属性修改,还没有设置。而调用他的observer方法就可以完成这一步:

var domTarget = 你想要监听的dom节点
mo.observe(domTarget, {
   characterData: true //说明监听文本内容的修改。
})

在nextTick中 MutationObserver的作用就如上图所示。在监听到DOM更新后,调用回调函数。