theme: channing-cyan
highlight: monokai
嵌套
副作用函数是会嵌套的:
effect(function effectFn1 (){ effect function effectFn2 () { }})
当effectFn1
执行时, effectFn2
肯定会执行, 在 Vue.js 中的渲染函数就是在一个副作用函数中执行, 当组件发成嵌套时是就会呈现副作用函数的嵌套:
effect(() => { Foo.render() effect(() => { Bar.render() })})
在以后的版本中若effectFn1
所绑定的属性产生获取操作时, 只会执行effectFn2
, 因为设置了一个全局变量贮存以后激活的副作用函数,就意味着在同一时刻, 该变量存储的副作用函数只有一个. 在初始化之后, 该全局变量贮存的是effectFn2
.
函数栈
为解决嵌套的产生的问题, 能够用函数栈, 在副作用函数执行时, 将以后的副作用函数压入栈, 当副作用函数执行完结后弹出栈, 并让activeEffect
始终指向栈顶的副作用函数
// 全局变量贮存以后激活的 effect 函数let activeEffectconst 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()}