浅表的说会给effect 增加一些属性
- effect.id = ++uid // 唯一的标识
- effect.allowRecurse=!!options.allowRecurse // 是否允许运行effect重复执行
- effect.__isEffect // 是不是effect
- effect.active // 当前effect是不是激活的状态
- effect.raw // effect对应的原函数
- effect.deps // effect对应了哪些属性 每个属性会做依赖收集放在外边的变量相当于放到自身了 deps[dep = new Set()]
// effect(()=>{state.name;state.age}); // 可以说name和age依赖了effect 如果同一个属性已经包含过相同的effect就不要在保存了依赖了。
- cleanup(effect) // 每次重新收集依赖,每次重新执行effect都会重新取值,那么调用get方法,重新进行依赖收集。 为什么每次重新都需要收集?
- effect默认没写lazy 就会默认执行一次
// track
const state = reactive({name:'pwd', age: ''})
effect(() => {
if(state.name === 'pwd') {
console.log(state.age)
}
}) // 默认第一次 render
state.age = 1
state.name = 'aaa'
state.age = 200
effect执行几次?
const sttae = reactive({name:1});
effect(()=>{
state.name;
})
state.name = 123;
1. fn 是否是effect
2. 如果是把effect 的原函数拿出来 fn.raw
3. 创建effect 注意不管有没有raw每次创建的都是新的
4. 如果lazy不是true就立即执行。
5. 把当前的effect放到栈里面来
6. cleanup 就是把 deps[i].delete(effect)
7. 走到track流程
8. 修改属性 走trigger triigger 和 track一个包 会从 deps上把目标对象拿出来拿到对应属性对应的effect执行它
9. 去重复防止重复执行effect
10. 是不是清理的清空所有的effect
11. 是不是访问的length 数组特殊处理
12. 收到effects 统一的执行
13. effects.forEach 所有的内容都执行一下run
14. run 看一下effect.options.ontrigger 是否有 ontrigger 如果有就调用 ontrigger
15. 如果有scheduler 就调用 scheduler
16. 如果 scheduler 都没有才会让 effect去执行
带有scheduler的effect
const sttae = reactive({name:1});
effect(()=>{state}, {
scheduler: (effect) => {
console.log("up")
}
})
state.name = 1;
17. effect用作watchAPI 比较多一些 watch基于effect实现的 组件也是基于effect的