之前对于 Vue 的响应式封装(这里主要思考的是 computed),主要是用用,其实是懒得思考背后的原理的。毕竟原理其实可以用一句话说明:计算属性对别的属性产生有向的依赖关系,这个依赖关系构成一个有向无环图(DAG),图上的某个节点更新后重新计算其所有后置节点即可。
但是仔细想来,内部其实有一些时间复杂度的问题。显然,我们不能暴力调用回调函数(会卡出指数级时间复杂度 下面会详细解释)。同时朴素的做法很难解决这样的问题:
const a = ref([]);
const b = computed(() => a.join(","));
for (let i = 1; i <= n; i++) {
a.value = a.value.concat([i]);
}
注意到对于一个网页而言,我们实际上期望 b
能在整个宏任务跑完以后才更新。所以实际上a.value
的 setter 触发的更新必须要进行推迟。
这篇文章讲讲我怎么在思考这些的过程中试着复刻一个 vue 的计算属性 computed
的