嵌套
副作用函数是会嵌套的:
effect(function effectFn1 (){
effect function effectFn2 () {
}
})
当effectFn1
执行时, effectFn2
一定会执行, 在 Vue.js 中的渲染函数就是在一个副作用函数中执行, 当组件发成嵌套时是就会出现副作用函数的嵌套:
effect(() => {
Foo.render()
effect(() => {
Bar.render()
})
})
在当前的版本中若effectFn1
所绑定的属性发生获取操作时, 只会执行effectFn2
, 因为设置了一个全局变量储存当前激活的副作用函数,就意味着在同一时刻, 该变量存储的副作用函数只有一个. 在初始化之后, 该全局变量储存的是effectFn2
.
函数栈
为解决嵌套的产生的问题, 可以用函数栈, 在副作用函数执行时, 将当前的副作用函数压入栈, 当副作用函数执行结束后弹出栈, 并让activeEffect
始终指向栈顶的副作用函数
// 全局变量储存当前激活的 effect 函数
let activeEffect
const effectStack = []
function effect(fn) {
const effectFn = () => {
cleanup(effectFn)
// 调用当前的副作用函数时, 赋值给 全局变量
activeEffect = effectFn
// 在调用副作用函数之前将该函数压入栈
effectStack.push(effectFn)
fn()
// 当前的副作用函数执行结束后, 出栈
effectStrack.pop()
// activeEffect 还原为之前的值
activeEffect = effectStack[effectStack.length - 1]
}
effectFn.desp = []
effectFn()
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。