nextTick
咱们先把这部分源码复制出来
var isUsingMicroTask = false;//nextTick 最终是否以微任务执行,在下面如果浏览器支持promise和MutationObserver的话,这个就会改变成true
var callbacks = [];//用来存放nextTick传进来的函数
var pending = false;
function nextTick(cb, ctx) {
var _resolve;
//callbacks在这里是存放传进来的cb
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;
});
}
}
timerFunc
这里主要使用了Promise.then > MutationObserver > setImmediate > setTimeOut;这四种来实现异步,然后优先级就是这样
这里主要是在页面刚引入vue.js的时候,进行判断,看看当前环境是不是支持,咱们可以在这里加上console.log,然后再浏览器里面看看
var timerFunc;
// 这里优先使用Promise,因为promise的then是微任务,执行速度比较快
if (typeof Promise !== 'undefined' && isNative(Promise)) {
console.log('这里使用了Promise')
var p_1 = Promise.resolve();
timerFunc = function () {
p_1.then(flushCallbacks);
if (isIOS)
setTimeout(noop);
};
isUsingMicroTask = true;
}
else if (!isIE &&
typeof MutationObserver !== 'undefined' &&
(isNative(MutationObserver) ||
MutationObserver.toString() === '[object MutationObserverConstructor]')) {
console.log('这里使用了MutationObserver')
var counter_1 = 1;
var observer = new MutationObserver(flushCallbacks);
var textNode_1 = document.createTextNode(String(counter_1));
observer.observe(textNode_1, {
characterData: true
});
timerFunc = function () {
counter_1 = (counter_1 + 1) % 2;
textNode_1.data = String(counter_1);
};
isUsingMicroTask = true;
}
else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
console.log('这里使用了setImmediate')
timerFunc = function () {
setImmediate(flushCallbacks);
};
}
else {
// 这里最后使用setTimeout,
console.log('这里使用了setTimeout')
timerFunc = function () {
setTimeout(flushCallbacks, 0);
};
}
查看打印的结果,看到当前浏览器是支持promise

image.png
flushCallbacks
function flushCallbacks() {
pending = false;
// 这里复制了一份出来,同时清空callbacks
var copies = callbacks.slice(0);
callbacks.length = 0;
// 这里遍历copies里面的函数,然后按顺序执行
for (var i = 0; i < copies.length; i++) {
copies[i]();
}
}