一、场景
effect(function effectFn1() {
console.log('effectFn1 执行')
effect(function effectFn2() {
console.log('effectFn2 执行')
temp2 = obj.bar // 在 effectFn2 中读取 obj.bar 属性
})
// 在 effectFn1 中读取 obj.foo 属性
temp1 = obj.foo
})
01 data
02 └── foo
03 └── effectFn1
04 └── bar
05 └── effectFn2
修改obj.foo,执行结果。前两个是初始的时候,修改完obj.foo,为啥是console.log('effectFn2 执行')打印呢?
原因就在于我们实现的 effect 函数与 activeEffect 上,我们用全局变量 activeEffect 来存储通过 effect 函数注册的 副作用函数,这意味着同一时刻 activeEffect 所存储的副作用函数 只能有一个。当发生嵌套的时候,会覆盖。并且永远不会恢复到原来的值。
let activeEffect // 用一个全局变量存储当前激活的 effect 函数
const effectStack = [] // 新增 effect 栈
function effect(fn) {
const effectFn = () => {
cleanup(effectFn)
activeEffect = effectFn
effectStack.push(effectFn) // 新增 // 在调用副作用函数之前将当前副作用函数压入栈中
fn()
//当前副作用函数执行完毕后,将当前副作用函数弹出栈,并把 activeEffect 还原为之前的值
effectStack.pop() // 新增
activeEffect = effectStack[effectStack.length - 1] // 新增
}
effectFn.deps = []
effectFn() // 执行副作用函数
}