at vue.js的高级功能从头开始 evan做出了一点任务。
- 使用两种方法创建
Dep
类:depend
和notify
。- 创建一个
autorun
功能,该功能采用更新器功能。- 在更新器功能中,您可以通过调用
明确地取决于dep.depend()
Dep
的实例- 稍后,您可以触发更新程序功能,以再次调用
dep.notify()
。
全部用法应该像这样:
const dep = new Dep()
autorun(() => {
dep.depend()
console.log('updated')
})
// should log: "updated"
dep.notify()
// should log: "updated"
该任务的想法是在vue中显示依赖性的逻辑。
解决方案
<script>
// a class representing a dependency
// exposing it on window is necessary for testing
window.Dep = class Dep {
constructor () {
this.subscribers = new Set()
}
depend () {
if (activeUpdate) {
// register the current active update as a subscriber
this.subscribers.add(activeUpdate)
}
}
notify () {
// run all subscriber functions
this.subscribers.forEach(subscriber => subscriber())
}
}
let activeUpdate
function autorun (update) {
function wrappedUpdate () {
activeUpdate = wrappedUpdate
update()
activeUpdate = null
}
wrappedUpdate()
}
</script>
我不明白为什么我们在代码中使用activeUpdate
和wrappedUpdate
。埃文解释说
我们正在将
wrappedUpdate
注册为activeUpdate
,因此当我们的依赖性更改并且update
函数再次称为时,我们实际上再次调用wrappedUpdate
。我们需要使我们的小依赖技巧仍在进行未来的迭代效果,并且不断收集所有依赖性。这很重要,因为在某些情况下,我们的update
函数可能包含条件(如果true
-此依赖关系,则false
-其他)。我们的依赖收集系统应动态重新平衡,并始终保持依赖关系的最新状态。
任何人都可以解释它如何工作?
首先,我们在这里没有提升/时间死区问题。由于dep.depend()
始终会在全局范围中找到activeUpdate
变量,除非我们在声明该变量之前调用该方法。
为什么
activeUpdate
?
对于正确的依赖性跟踪,我们需要一个工具来指示我们在当前正在运行的功能中。这就是使用activeUpdate
变量的重点 - 以表示我们在wrappedUpdate
功能中,我们即将更新依赖关系。
为什么
wrappedFunction
?
我们希望在调用依赖关系和update
函数时,请检查一下新的订户。它看起来像是一系列电话:
notify-->包装update-> dep.depperdeviprate()
通过activeUpdate
,我们检查我们的依赖性是否由于某些条件而更改。如果有 - 我们将其注册在 subscriber Set
中,如果它已经在Set
中 - 我们忽略了添加。