4.4 分支切换与cleanup
解决分支切换与 cleanup 的思路很简单,每次副作用函数执行,我们可以先把它从所有与之关联的依赖集合中删除。(P52页)
我对上文的理解:
activeEffect = 我
activeEffect.deps = 我的收藏夹
依赖集合 = 花名册(含各种名单)
我 在 极客时间前端训练班 的名单中
我 在 慕课网前端训练班 的名单中
我 在 拉勾网全栈训练班 的名单中
在老师上课签到前,翻开我的收藏夹,找到有我名字的名单,把我的名字从所有花名册中删掉,在我进教室的时候再把自己加到所有名单中
关键的修改:
1. 注册副作用函数时,重新对其包装
const effect = (fn) => {
const effectFn = () => { // 包装后的副作用函数
cleanUp(effectFn)
activeEffect = effectFn
fn()
}
// 定义一个数组用于存储包含此副作用函数的依赖集合
effectFn.deps = []
effectFn()
}
2. 新增 cleanup 函数,在执行副作用函数前运行,删除依赖集合中的待执行的副作用函数 activeEffect
function cleanup (effectFn) {
// 遍历 effectFn.deps 数组
for (let i = 0; i < effectFn.deps.length; i++) {
// deps 是依赖集合
const deps = effectFn.deps[i]
// 将 effectFn 从依赖集合中移除
deps.delete(effectFn)
}
// 最后需要重置 effectFn.deps 数组
effectFn.deps.length = 0
}
3. 修改 track
序号1代码 effectFn() 执行时,先将自己从依赖集合的名单中剔除;
然后将当前执行函数赋值到 activeEffect;
当运行 fn() 时,函数体中有读取原始数据的操作,随即进入代理中的 get 方法,在 track 中将包含 activeEffect 函数的集合 push 到其 deps 数组中
activeEffect.deps.push(deps)