const bucket = new WeakMap();
let activeEffect = null;
const effectStack = [];
//封装收集副作用函数
function track(target,key){
if(!activeEffect){
return target[key]
}
//取出与target绑定的map
let depsMap = bucket.get(target);
if(!depsMap){
bucket.set(target, (depsMap = new Map()));
}
//取出与key对应的副作用函数
let depsEffets = depsMap.get(key);
if(!depsEffets){
depsMap.set(key, (depsEffets = new Set()));
}
depsEffets.add(activeEffect);
activeEffect.deps.push(depsEffets)
}
//封装触发副作用函数
function trigger(target, key){
const depsMap = bucket.get(target);
if(!depsMap){
return
}
const depsEffets = depsMap.get(key);
const effectsToRun = new Set();
depsEffets.forEach(effectfn=>{
if(effectfn!==activeEffect){
effectsToRun.add(effectfn)
}
})
effectsToRun&&effectsToRun.forEach(fn=>{
if(fn.option.scheduler){
fn.option.scheduler(fn)
}else{
fn()
}
});
}
function reactive(data){
const obj = new Proxy(data, {
get(target, key){
track(target, key);
return target[key];
},
set(target, key, value){
target[key] = value;
trigger(target,key,value);
return true;
}
})
return obj;
}
const cleanup = (effectFn) => {
for(let i=0;i<effectFn.deps.length; i++){
const deps = effectFn.deps[i];
deps.delete(effectFn)
}
effectFn.deps.length = 0;
}
const effect = (fn, option={})=>{
const effectFn = () => {
cleanup(effectFn)
activeEffect = effectFn;
effectStack.push(activeEffect);
fn();
effectStack.pop();
activeEffect = effectStack[effectStack.length-1];
}
effectFn.option = option;
effectFn.deps = []
effectFn();
};
const obj1 = reactive({name: "李翔", ok:true, age: 1})
effect(function effectfn(){
console.log(obj1.age)
},{
scheduler(effectfn){
setTimeout(effectfn)
}
})
obj1.age++;
console.log('结束了')
console