讀了第四章里的調(diào)度講解,在此記錄理解
所謂可調(diào)度,指的是當(dāng) trigger 動作觸發(fā)副作用函數(shù)重新執(zhí)行時,有能力決定副作用函數(shù)執(zhí)行的時機(jī)、次數(shù)以及方式。
決定調(diào)度時機(jī)的執(zhí)行
const data = {foo:1}
const bucket = new WeakMap()
let activeEffect;
const effectStack = []
function effect(fn,options={}){
const effectFn = ()=>{
cleanup(effectFn)
activeEffect = effectFn;
effectStack.push(effectFn)
fn()
// 當(dāng)副作用函數(shù)執(zhí)行完畢后,將當(dāng)前副作用函數(shù)彈出棧,并把a(bǔ)ctiveEffect還原之前的值
effectStack.pop()
activeEffect = effectStack[effectStack.length-1]
}
// 將options掛載到effectFn函數(shù)上
effectFn.options = options
effectFn.deps=[]
effectFn()
}
function cleanup(effectFn){
for(let i=0;i<effectFn.deps.length;i++){
effectFn.deps[i].delete(effectFn)
}
effectFn.deps.length = 0
}
function track(target,key){
if(!activeEffect) return
let depsMap = bucket.get(target)
if(!depsMap){bucket.set(target,depsMap=new Map())}
let deps = depsMap.get(key)
if(!deps){depsMap.set(key,deps=new Set())}
deps.add(activeEffect)
activeEffect.deps.push(deps)
}
function trigger(target,key){
let depsMap = bucket.get(target)
if(!depsMap) return
const effects=depsMap.get(key)
const effectsToRun = new Set()
effects && effects.forEach(effectFn=>{
if(effectFn!==activeEffect){
effectsToRun.add(effectFn)
}
})
console.error(effectsToRun)
effectsToRun.forEach(effectFn=>{
if(effectFn.options.scheduler){
// 如果有調(diào)度函數(shù),則執(zhí)行調(diào)度函數(shù)
effectFn.options.scheduler(effectFn)
}else{
effectFn()
}
})
}
const obj = new Proxy(data,{
get(target,key){
track(target,key)
return target[key]
},
set(target,key,newVal){
target[key] = newVal
trigger(target,key)
}
})
effect(
function effectFn1(){
console.log(obj.foo)
},
// options
{
scheduler(fn){
// 將副作用函數(shù)放到宏任務(wù)隊列中執(zhí)行
setTimeout(fn)
}
}
)
obj.foo++
console.log('結(jié)束了')
沒有調(diào)度時正常打印順序是:1,2,結(jié)束了
調(diào)度后打印:

image.png