理解副作用函数
产生副作用你的函数 : 当某个函数的执行会影响到其它函数的执行,就叫做副作用函数。
let obj.temp = "hello"
function effect(){
document.body.innerText = obj.temp
// body.innerText 该变量其它函数都可以直接读取
}
换句话说某个函数执行过程中修改了全局变量的值。
理解响应式数据
响应式数据 obj.temp 变量被读取或者修改后 我们希望它触发副作用函数的执行。
思路就是拦截对象的读取和设置操作。
const obj = new Proxy(data,{
get(target,key){
// 将副作用函数反在桶里
bucket.add(effect) // 副作用函数只能叫这个吗?
return target[key]
},
set(target,key,newVal){
target[key] = new Val
// 将副作用函数从桶子里面拿出来
bucket.forEach(item=>item())
}
})
副作用函数只能叫这个吗? 取别的名字不行吗?匿名函数也不行吗?
let activeEffect;
function effect(fn){
cont effectFn = ()=>{
activeEffect = fn
fn()
}
effectFn.deps=[]
// 副作用函数还得知道到底谁依赖我了啊 依赖数组
effectFn()
}
// 改下
const bucket= new WeapMap() // key 弱引用 可以触发垃圾回收 防止内存泄漏
const data = {
text:"123"
}
const obj = new Proxy(data,{
get(target,key){
// 有没有副作用函数,你要不要做其他的操作
if(!activeEffect) return target[key] // 不要直接返回
// 没有就创建一个目标对象和存储桶之间的链接
let depMaps = bucket.get(target);
if(!depMaps){
bucket.set(target,new Map())
}
let deps = depMaps.get(key) // 获取当前依赖的副作用函数集合
if(!deps){
depMaps.set(key,new Set())
}
deps.add(activeEffect) // 注册副作用函数 一个属性可能会依赖多个副作用函数
activeEffect.deps.push(deps) // 依赖收集
return target[key]
},
set(target,key,newVal){
target[key] = new Val
// 将副作用函数从桶子里面拿出来执行
let depMaps = bucket.get(target);
if(!depMaps) return
const effects= depMaps.get(key)
effects && effects.forEach(item=>item())
}
}
可以用到封装的思想
// track() 注册副作用函数到存储桶
// triggger() 将副作用函数从桶子里面拿出来执行
分支切换 会导致副作用函数的频繁触发?如何解决呢?
useEffect(()=>{
document.body.innerText = obj.ok ? '1213' : obj.text
})