let queue = [];
let has = {};
let pending = false;
function queueWatcher(watcher) {
const id = watcher.id; //对watcher进行去重
if (has[id] == null) {
queue.push(watcher); //并且将watcher存在队列中
has[id] = true;
// 等待所有同步代码执行完毕后在执行
if (!pending) { //如果还没清空队列,就不要再开定时器了。 防抖处理 多次调用只处理一次
/* setTimeout(() => {
queue.forEach(watcher => watcher.run());
queue = []; //清空watcher队列,为了下次使用
has = {}; //清空标识的id
pending=false;
}, 0); */
nextTick(flushScheduleQueue);
pending = true;
}
}
queue.push(watcher);
}
let queue = [];
function flushScheduleQueue(){
queue.forEach(watcher => {watcher.run();watcher.cb()});
queue = []; //清空watcher队列,为了下次使用
has = {}; //清空标识的id
pending=false;
}
const callbacks=[];
let pending=false;
function flushCallbacks(){
while(callbacks.length){
let cb=callbacks.pop();
cb();
}
pending=false; // 标识已经执行完毕
}
let timerFunc;
if(Promise){
timerFunc=()=>{
Promise.resolve().then(flushCallbacks); //异步处理更新
}
}else if(MutationObserver){ //可以监控dom变化,监控完毕后是异步更新
let observe=new MutationObserver(flushCallbacks);
let textNode=document.createTextNode(1);
observe.observe(textNode,{characterData:true});
timerFunc=()=>{
textNode.textContent=2; //文中的内容改成2
}
}else if(setImmediate){
timerFunc=()=>{
setImmediate(flushCallbacks);
}
}else{
timerFunc=()=>{
setTimeout(flushCallbacks);
}
}
export function nextTick(cb){ //因为内部都会调用nextTick 用户也会调用,但是异步只需一次。
callback.push(cb);
if(!pending){
// vue3 里的nextTick原理就是promise.then 没有做兼容性处理了。
timerFunc(); //这个方法是异步方法 做了兼容处理
pending=true;
}
}
export function stateMixin(Vue){
Vue.prototype.$nextTick=function(cb){
console.log(cb);
}
}
// 数据更新完成之后,调用vm.$nextTick(()=>{}) 异步批量更新 标识当前是否处理
// console.log(vm.$el.innerHTML);