关于Vue源码观察者的一个困惑
发布于 3 个月前 作者 banyungong 203 次浏览 来自 问答
粉丝福利 : 关注VUE中文社区公众号,回复视频领取粉丝福利
Watcher类中的一个方法
cleanupDeps () {
    let i = this.deps.length
    while (i--) {
      // 这一个是进行更新将旧的依赖框数组进行更新
      const dep = this.deps[i]
      if (!this.newDepIds.has(dep.id)) {
        // 遍历旧的deps,如果筐中存在的id在新的筐中不存在的话,进行从dep的依赖中删除,如果在newDepIds中不存在的id,则进行删除
        dep.removeSub(this)
      }
    }
    // 将newDepId和depId进行交换,从而避免申请新的内存,先进行id散列表的交换
    let tmp = this.depIds
    this.depIds = this.newDepIds
    this.newDepIds = tmp
    this.newDepIds.clear()  // 将newDepIds散列表进行清空。
    // 进行依赖框的交换
    tmp = this.deps
    this.deps = this.newDeps
    this.newDeps = tmp
    this.newDeps.length = 0
  }

文件的位置在src/core/observer/watcher.js
困惑在于while循环里面将deps中存在的项,如果不在newDeps中存在,那么该项就从deps中进行移除。然后下面由将新旧的依赖数组进行交换,并且将原本是旧的deps(现在是newDeps)清空。我想问的为什么要进行while里面的操作而不是直接进行交换后移除。

2 回复

watcher和dep相互依赖,各自都有包含对方的记录
更新依赖时,watcher需要while遍历通知不再依赖的dep删除watcher

若按你说的,直接进行交换删除 仅仅只是把watcher自己对dep的记录给删了
但已注册的dep里没有删掉这个已经不用通知的watcher

dep存放着与这个数据属性挂载的观察者对象实例,观察者对象的deps/newDeps数组则存放着挂载这个watcher实例的所有dep。懂了

回到顶部