- 为了实现响应式,我们使用了new Proxy
- effect默认数据变化要能更新,我们先将正在执行的effect作为全局变量,渲染(取值),然后在get方法中进行依赖收集
- 依赖收集的数据格式weakMap(对象:map(属性:set(effect))
- 用户数据发生变化,会通过对象属性来查找对应的effect集合,全部执行;
- 调度器的实现,创建effect时,把scheduler存在实例上,调用runner时,判断如果有调度器就调用调度器,否则执行runner
边界情况:
- 如果在执行effect时,又修改了这个effect的依赖,会出现递归调用,所以在trigger中遍历执行effect时,要判断将要执行的effect不是activeEffect;
export function trigger(target, type, key, value, oldValue) {
const depsMap = targetMap.get(target);
if (!depsMap) return;
let effects = depsMap.get(key);
if (effects) {
effects = new Set(effects);
effects.forEach((effect) => {
if (effect !== activeEffect) {
if (effect.scheduler) {
effect.scheduler();
} else {
effect.run();
}
}
});
}
}
-
如果effect存在分支情况,会导致不需要的依赖仍然存在,所以每次执行effect的回调时,要清空当前的effect.deps,把依赖全部删除,这样执行回调的时候重新收集依赖,就可以保证effect依赖的正确;
-
执行删除时,要注意需要将依赖的set删除,而不是直接把数组长度设置为0,另外为了防止一边删除一边新增,导致死循环,在执行时,需要先把原来的数组保存一份,遍历保存后的数组;