Vue.js从头开始的高级功能 Evan做了一个小任务。
- 使用两种方法创建
Dep
课程:depend
和notify
。- 创建一个带有更新程序功能的
autorun
函数。- 在更新程序功能中,您可以通过调用
明确依赖Dep
dep.depend()
的实例- 稍后,您可以通过调用
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
- 另一个)。我们的依赖性收集系统应该动态地重新平衡并始终保持依赖性是最新的。
任何人都可以解释它是如何运作的吗?
答案 0 :(得分:0)
首先,我们这里没有吊装/暂时死区问题。因为dep.depend()
总是在全局范围内找到activeUpdate
变量,除非我们在声明该变量之前调用该方法。
为什么
activeUpdate
?
为了正确的依赖关系跟踪,我们需要一个工具来指示我们在当前正在运行的函数内部。这是使用activeUpdate
变量的信号 - 表示我们在wrappedUpdate
函数内,我们即将更新我们的依赖项。
为什么
wrappedFunction
?
我们想要在我们的依赖项更改并调用update
函数时检查新订阅者。它看起来像一连串的电话:
通知 - &gt; wrappedUpdate - &gt; dep.depend()
并通过activeUpdate
检查我们的依赖关系是否因某些条件而被更改。如果有 - 我们在订阅者Set
中注册,如果它已经在Set
中 - 我们会忽略添加。