dependence tracking 实现依赖跟踪
??这是什么意思??
举个例子:
a = 10;
b= a*3
要求当a改变了b同时跟着改变, b依赖于a 这就是依赖跟踪 。 a是被依赖项。
要求:
- Create a
Dep
class with two methods:depend
andnotify
. - Create an
autorun
function that takes an updater function. - Inside the updater function, you can explicitly depend on an instance of
Dep
by callingdep.depend()
- Later, you can trigger the updater function to run again by calling `dep.notify()
- 创建一个Dep类,它有两个方法depend() 和notify()
- 创建一个autorun 函数,参数接受一个更新函数 update()
- depend() 当前正在执行的代码,收集订阅者
- notify() 依赖发生改变 ,依赖于它的对象(计算 数据 表达式)被通知更新。
这里其实是创建一个小型的订阅系统。
autorun 其实就是订阅者了才能被通知。
还有一个会误解的知识点,
先解决:
let a = new Set()
function x() {
console.log(1234);
}
a.add(x)
a.forEach(subscriber => subscriber())
一开始我有点蒙,这个subscrber()是一个Set的函数吗?
后来实践一下是 x(){}
其实就是forEach语法 subscriber = x ,x+()不就是执行x()的意思吗。。。。
window.Dep = class Dep {
constructor() {
this.subscribers = new Set()
}
depend() {
if (activeUpdate) {
// register the current active update as a subscriber
this.subscribers.add(activeUpdate)
//把activeUpdate函数加入订阅器 其实
}
}
notify() {
// run all subscriber functions
console.log(this.subscribers);
this.subscribers.forEach(subscriber => subscriber())
//通知订阅者运行update函数
}
}
let activeUpdate
function autorun(update) {
function wrappedUpdate() {
activeUpdate = wrappedUpdate
update()
activeUpdate = null
}
wrappedUpdate()
}
把上一节的合并起来:
<body>
<input type="text" id="in" />
<div id='countview'></div>
<script>
function isObject(obj) {
return typeof obj === 'object' &&
!Array.isArray(obj) &&
obj !== null &&
obj !== undefined
}
function observe(obj) {
if (!isObject(obj)) {
throw new TypeError()
}
Object.keys(obj).forEach(key => {
let internalValue = obj[key]
let dep = new Dep()
Object.defineProperty(obj, key, {
get() {
dep.depend() //加人依赖收集
return internalValue
},
set(newValue) {
const isChanged = internalValue !== newValue
if (isChanged) {
internalValue = newValue
dep.notify()
}
}
})
})
}
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
console.log(this.subscribers);
this.subscribers.forEach(subscriber => subscriber())
}
}
let activeUpdate
function autorun(update) {
function wrappedUpdate() {
activeUpdate = wrappedUpdate
update()
activeUpdate = null
}
wrappedUpdate()
}
const state = {
count: 0,
}
let cv = document.getElementById('countview');
let inp = document.getElementById('in');
inp.oninput = function(e) {
state.count = this.value;
}
observe(state); //观察者开始观察state
autorun(() => { //该函数相当于订阅者
cv.innerHTML = state.count; // 触发通知时候要做的事
inp.value = state.count;
})
</script>
</body>
效果
绑定原理,
实质上订阅者应该还要写,用于视图。也就是watcher。继续看尤大神视频。