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; }); }}