# nextTick

在执行queueWatcher的时候会调用nextTick()

export function queueWatcher(watcher: Watcher) {
  // ...
  if (!waiting) {
    // ...
    nextTick(flushSchedulerQueue);
  }
}

或者说自己定义的时候也可以调用

this.nextTick(() => {
  console.log(this.$ref.dom);
});

最终调用的都是nextTick方法

export function nextTick(cb?: Function, ctx?: Object) {
  let _resolve;
  callbacks.push(() => {
    if (cb) {
      try {
        cb.call(ctx);
      } catch (e) {
        handleError(e, ctx, "nextTick");
      }
    } else if (_resolve) {
      _resolve(ctx);
    }
  });
  if (!pending) {
    pending = true;
    timerFunc();
  }
  // $flow-disable-line
  if (!cb && typeof Promise !== "undefined") {
    return new Promise((resolve) => {
      _resolve = resolve;
    });
  }
}

首先会把传入进来的函数cb收集到callbacks,然后判断是否pending,执行timerFunc方法。

let timerFunc;

if (typeof Promise !== "undefined" && isNative(Promise)) {
  const p = Promise.resolve();
  timerFunc = () => {
    p.then(flushCallbacks);
    if (isIOS) setTimeout(noop);
  };
  isUsingMicroTask = true;
} else if (
  !isIE &&
  typeof MutationObserver !== "undefined" &&
  (isNative(MutationObserver) ||
    // PhantomJS and iOS 7.x
    MutationObserver.toString() === "[object MutationObserverConstructor]")
) {
  let counter = 1;
  const observer = new MutationObserver(flushCallbacks);
  const textNode = document.createTextNode(String(counter));
  observer.observe(textNode, {
    characterData: true,
  });
  timerFunc = () => {
    counter = (counter + 1) % 2;
    textNode.data = String(counter);
  };
  isUsingMicroTask = true;
} else if (typeof setImmediate !== "undefined" && isNative(setImmediate)) {
  timerFunc = () => {
    setImmediate(flushCallbacks);
  };
} else {
  timerFunc = () => {
    setTimeout(flushCallbacks, 0);
  };
}

timerFunc是一个降级的方法,默认是直接使用Promise,最后降级为setTimeout。执行timerFunc之后,会执行p.then(flushCallbacks),将flushCallbacks函数放到微任务队列中。

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

flushCallbacks比较简单,就是还原pending,依次执行callbacks内的方法。