@xachary 2024-01-31 15:02 采纳率: 100%
浏览 6
已结题

vue3 原理关于 trackEffect 的疑问

Vue3的packages\reactivity\src\effect.ts中的trackEffect方法:

export function trackEffect(
  effect: ReactiveEffect,
  dep: Dep,
  debuggerEventExtraInfo?: DebuggerEventExtraInfo,
) {
  if (dep.get(effect) !== effect._trackId) {
    dep.set(effect, effect._trackId)
    const oldDep = effect.deps[effect._depsLength] // 这里貌似永远都是 undefined
    if (oldDep !== dep) { // 那么这里永远为 true,除非 dep 是 undefined(可能吗?)
      if (oldDep) {
        // 那么,感觉永远执行不到这里
        cleanupDepEffect(oldDep, effect)
      }
      // 这里相当于 effect.deps[effect._depsLength] = dep 后 effect._depsLength++
      // effect._depsLength++ 后,它指向了数组尾部空位置
      // 例如:起初effect._depsLength === 0,执行 effect.deps[0] = dep1 后,effect.deps === [dep1]
      // effect._depsLength++ 后为 1,则 effect.deps[0] === dep1,effect.deps[1] === undefined
      // 回过头看看 const oldDep = effect.deps[effect._depsLength]
      effect.deps[effect._depsLength++] = dep
    } else {
      // 那么,感觉也永远执行不到这里
      effect._depsLength++
    }
    if (__DEV__) {
      effect.onTrack?.(extend({ effect }, debuggerEventExtraInfo!))
    }
  }
}

请问什么情况下 oldDep 不为 undefined?

  • 写回答

4条回答 默认 最新

  • @xachary 2024-01-31 15:33
    关注

    拿一个极简的场景测试:

    img


    会发现,改变count的时候,_depsLength重置为0,调试发现:
    onClick->set->trigger->...->run(ReactiveEffect)->preCleanupEffect 的时候

    function preCleanupEffect(effect: ReactiveEffect) {
      effect._trackId++
      effect._depsLength = 0 // 重置为0了
    }
    

    这就解答了问题根源所在。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 2月8日
  • 已采纳回答 1月31日
  • 创建了问题 1月31日