Vue3 watch函數執行過程

第一次寫這種文章,理解應該不深,望各位dalao們指點指點javascript

bb不來,純乾貨java

Vue3 watch執行過程

Vue.watch(() => {
    console.log("watch OK!!!");
    app.querySelector('p').textContent = count.value;
});
複製代碼

調用watch

// 簡化後
export function watch(effectOrSource, effectOrOptions,options) {
  if (isFunction(effectOrOptions)) {
  } else {
   // 執行這裏
    return doWatch(effectOrSource, null, effectOrOptions)
  }
}
複製代碼

doWatch (代碼有點長,直接說一下流程吧)

doWatch(source,cb,options){
    // source 爲fn 其餘 在這裏都不重要
    
    // 1. 將source 處理成 getter
    // 2. 將getter 打包成
    // 3.經過effect 打包成一個訂閱函數 即 runner 變量
    // 3.1 ps: effect 很重要 下面列出了函數代碼
    // 4. 執行 scheduler (scheduler是判斷flush獲得的)
    let scheduler = job => {
      queuePostRenderEffect(job, suspense)
    }
    // 5.執行 queuePostRenderEffect 後 會將函數添加到隊列並執行它 
    // 5.1 `下面列出了這個函數`
    // 6.end 這個函數的事情作完了
}

// 這個函數會執行queuePostFlushCb而後將訂閱函數放入(任務)隊列
function queuePostRenderEffect(fn,suspense){
if (suspense !== null && !suspense.isResolved) {
   // 不重要
  } else {
    // 執行 queuePostFlushCb 
    queuePostFlushCb(fn)
  }
}
// 這個函數最大的功能就是 執行nextTick和添加隊列
function queuePostFlushCb(cb: Function | Function[]) {
    // ...
    // 一些不重要的代碼
    // ...
    // isFlushing不重要 最終會 執行 nextTick
      if (!isFlushing) {
        nextTick(flushJobs)
      }
}
// 異步執行函數
function nextTick(fn?: () => void) {
    return fn ? p.then(fn) : p
}

複製代碼

effect 函數(訂閱函數)

effect( fn,options) {
    // ...
    // 一些不重要的代碼
    // ...
    // 創造一個 effect對象 用於綁定一些屬性和不容許重複綁定
    const effect = createReactiveEffect(fn, options)
    // ...
    // 一些不重要的代碼
    // ...
    return effect
}

// 建立訂閱函數
function createReactiveEffect(fn, options) {

    const effect = function effect(...args) {
        // run 函數 下面貼了代碼
        return run(effect as ReactiveEffect, fn, args)
    }

    effect.isEffect = true
    effect.active = true
    effect.raw = fn
    effect.scheduler = options.scheduler
    effect.onTrack = options.onTrack
    effect.onTrigger = options.onTrigger
    effect.onStop = options.onStop
    effect.computed = options.computed
    effect.deps = []
    return effect
}
複製代碼

run 函數 (大概的理解,若有問題麻煩了)

// 將訂閱函數添加到 等待隊列後,執行fn函數
// 若是fn中有 可觸發的data getter 就將函數訂閱到該發佈者 // 這裏不知道怎麼說了

function run(effect: ReactiveEffect, fn: Function, args: any[]): any {
  // 當 active 被中止 就不須要了訂閱了 直接綁定便可
  if (!effect.active) {
    return fn(...args)
  }
  // 若是隊列中不存在就表示此effect能夠被訂閱
  if (activeReactiveEffectStack.indexOf(effect) === -1) {
    cleanup(effect)
    try {
      // 先將 effect 添加到 等待訂閱的隊列
      activeReactiveEffectStack.push(effect)
      // 執行以後會觸發getter 而後將effect訂閱到隊列
      return fn(...args)
    } finally {
      // 當訂閱以後就退出來
      activeReactiveEffectStack.pop()
    }
  }
}

複製代碼
相關文章
相關標籤/搜索