如何建立自己的反应系统
如何建立自己的反应系统
原文:https://medium.com/hackernoon/how-to-build-your-own-reactivity-system-fc48863a1b7c

想了解 Vuex?检查我的 手动课程 !。给我发消息成为早期评论者,免费获得。
几个月前,我在[update() 。该方法使用旧值和新值作为参数调用构造函数中提供的回调函数。当 Dep#notify() 方法在它的值改变后对它的每个订阅者调用update时,就会用到它。](https://medium.com/u/1b199ed2dfd#depend() 方法调用,我们将在下一节更详细地讨论这个方法。<li id=)
[下面是我们的 观察者 类的代码:](https://medium.com/u/1b199ed2dfd#depend() 方法调用,我们将在下一节更详细地讨论这个方法。<li id=)
[defineReactive()](https://medium.com/u/1b199ed2dfd#depend() 方法调用,我们将在下一节更详细地讨论这个方法。<li id=)
[根据](https://medium.com/u/1b199ed2dfd#depend() 方法调用,我们将在下一节更详细地讨论这个方法。<li id=)源代码、defineReactive()、、“定义一个对象上的反应属性”。这是通过向给定对象的给定属性添加 getters 和 setters 来实现的。每个属性都有一个 Dep 实例与之相关联。每当访问一个反应对象的属性时,getter 调用 Dep#depend(),将当前目标 Watcher 作为订阅者添加到属性的 Dep 实例中。每当属性被更改时,setter 调用 Dep#notify() ,后者调用属性的 Dep 的每个订阅者的 update() 方法。下面是 defineReactive() ,基于源代码:
这一切是如何协同工作的
现在我们已经写了反应系统的每一部分,但是它是如何工作的呢?系统的每个部分都与所有其他部分紧密相连,因此很难理解。让我们一步一步地看看在我们的 观察器 类的示例用法中发生了什么。
我们将从设置好一切开始:
const foods = { apple: 5 }// make foods reactive, register deps for each property
walk(foods)// Instantiate the watcher, which takes a getter and a callback
const foodsWatcher = new Watcher(() => foods.apple,
() => console.log('change')
)
首先, 观察器 类的构造函数运行如下:
this.value = this.get()
下面是观察者#get() :
pushTarget(this) // Imported from dep.js
const value = this.getter()
popTarget() // Imported from dep.jsreturn value
首先,它调用pushTarget() 函数,将this*foodsWatcher)赋值给Dep.target。然后,它调用this.getter() ,*第一个函数传递给 **观察器 构造器。foodsWatcher 的 getter 只是返回foods.apple的值。由于foods.apple是由defineReactive() ,激活的,它也将运行激活的 getter:****
**// adds Dep.target as a subscriber to the property's dep instance
dep.depend()return value**
**这将foodsWatcher注册为与foods.apple关联的 **Dep 实例的订阅者。所以现在在foodsWatcher和foods.apple之间有一个连接。****
这有什么帮助?假设我们改变foods.apple。
**foods.apple = 6**
**这样做将调用foods.apple上的 setter。setter 运行dep.notify(),而在 dep 的每个订户上调用update() 。由于foodsWatcher是 **Dep 实例的订阅者,因此dep.notify() 调用将触发foodsWatcher上的更新方法。 Watcher#update() 是做什么的?****
**update() {
const value = this.get()
const oldValue = this.value
this.value = value this.cb(value, oldValue)
}**
它更新其对当前值的了解,然后调用构造函数中提供的回调。记得我们指定的回调是
**() => console.log('change')**
**所以,当我们改变`foods.apple`时,我们的反应系统会让我们知道!最酷的是,这种情况的发生并没有每毫秒进行一次脏检查。它的发生不需要我们显式地设置状态。它就是起作用了,根本不用我们去想它,就像一个电子表格。这就是 Vue 的反应系统如此不可思议的原因。**
如果你想在一个地方看到我们反应系统的所有代码,我做了一个非常酷的演示。感谢阅读!