$nexttick - vue2 源码

52 阅读1分钟

1、flushCallbacks

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

2、timerFunc

var timerFunc;
if (typeof Promise !== "undefined" && isNative(Promise)) {  var p = Promise.resolve();  timerFunc = function () {    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]")) {  // Use MutationObserver where native Promise is not available,  // e.g. PhantomJS, iOS7, Android 4.4  // (#6466 MutationObserver is unreliable in IE11)  var counter = 1;  var observer = new MutationObserver(flushCallbacks);  var textNode = document.createTextNode(String(counter));  observer.observe(textNode, {    characterData: true,  });  timerFunc = function () {    counter = (counter + 1) % 2;    textNode.data = String(counter);  };  isUsingMicroTask = true;} else if (typeof setImmediate !== "undefined" && isNative(setImmediate)) {  // Fallback to setImmediate.  // Technically it leverages the (macro) task queue,  // but it is still a better choice than setTimeout.  timerFunc = function () {    setImmediate(flushCallbacks);  };} else {  // Fallback to setTimeout.  timerFunc = function () {    setTimeout(flushCallbacks, 0);  };}

3、nextTick

function nextTick(cb, ctx) {  var _resolve;  callbacks.push(function () {    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(function (resolve) {      _resolve = resolve;    });  }}