vue.js設(shè)計與實現(xiàn)(四)-響應(yīng)系統(tǒng)-調(diào)度執(zhí)行-時機(jī)

讀了第四章里的調(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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容