跳到主要内容

模拟实现

2024年03月18日
柏拉文
越努力,越幸运

一、认识


一、Vue.js 2.0


let pending = false;
const callbacks = [];

function isNative(Ctor) {
return typeof Ctor === 'function' && /native code/.test(Ctor.toString());
}

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

let timerFunc;

if (typeof Promise !== 'undefined' && isNative(Promise)) {
const p = Promise.resolve();
timerFunc = () => {
p.then(flushCallbacks);
};
} else if (
typeof MutationObserver !== 'undefined' &&
isNative(MutationObserver)
) {
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);
};
} else if (typeof setImmediate !== 'undefined' && isNative(setImmediate)) {
timerFunc = () => {
setImmediate(flushCallbacks);
};
} else {
timerFunc = () => {
setTimeout(flushCallbacks);
};
}

function nextTick(cb, ctx) {
let _resolve;
callbacks.push(() => {
if (cb) {
try {
cb.call(ctx);
} catch (error) {
console.log('nextTick 函数发生错误');
}
} else if (_resolve) {
_resolve(ctx);
}
});

if (!pending) {
pending = true;
timerFunc();
}

if (!cb && typeof Promise !== 'undefined') {
return new Promise(resolve => {
_resolve = resolve;
});
}
}

二、Vue.js 3.0


function nextTick(fn) {
const p = Promise.resolve();
return fn ? p.then(fn) : p;
}

二、测试