文章参考了霍春阳的《Vue.js设计与实现》,是自己在阅读过程中的一些思考和理解
effect函数是可以嵌套的。但是在嵌套过程中:
effect(() => {
console.log('f1执行')
effect(() => {
console.log('f2执行')
let temp2 = proxy.text
})
let temp1 = proxy.ok //<--当前层的数据读取如果在最后,就会使得activeEffect指向内层effectfn
})
如果当前层的数据读取在最后,就会导致全局变量activeEffect指向内层的effectfn函数,从而使得当前层的Set集合中存储的是内层的effectfn。这是由于activeEffect只有一个,且覆盖上不可逆的。(但是如果在当前层的最开始就读取该层的数据,就可以避免)
因此加入effectStack全局变量,将当前副作用函数加入到栈中,执行完毕后再弹出栈,并将activeEffect指向栈顶的副作用函数,这样就可以避免这种情况,且中任何情况下都有效果。
function effect(fn) {
const effectfn = () => {
clearup(effectfn)
activeEffect = effectfn
effectStack.push(effectfn) // <---存储当前层的effectfn
fn()
effectStack.pop() // <---执行完毕后弹出该effectfn
activeEffect = effectStack[effectStack.length-1] //<--指向栈顶
}
effectfn.deps = []
effectfn()
}