-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcompleted-watcher.js
100 lines (85 loc) · 1.87 KB
/
completed-watcher.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
let target = null;
// (私人管家)依赖收集
class Dep {
constructor() {
this.subscriberList = [];
}
// 将当前的 watcher 加入 dep 中
addSub(watcher) {
this.subscriberList.push(watcher)
}
// 添加订阅方法
depend() {
if (target) {
target.addDep(this);
}
}
// 发布者更新消息,触发所有的订阅方法
notify() {
this.subscriberList.forEach(sub => {
sub.update();
});
}
}
// (平台)观察者
class Watcher {
constructor(data = {}, key = '', cb = () => {}) {
this.cb = cb;
this._data = data;
this.key = key;
target = this;
// 触发 getter,存储本 watcher
this.value = data[key];
// 防止反复触发
target = null;
}
addDep(dep) {
dep.addSub(this);
}
update() {
const newVal = this._data[this.key];
this.value = newVal;
this.cb(newVal);
}
}
// (发布者和管家的联系方式)监听器
function observer(data = {}) {
Object.keys(data).forEach(key => {
let val = data[key];
const dep = new Dep();
Object.defineProperty(data, key, {
get() {
if (target) {
// get 时添加依赖
dep.depend();
}
return val;
},
set(newVal) {
if (newVal === val) {
return;
}
// set 时触发更新
val = newVal;
dep.notify();
}
})
});
}
// 发布者
const publisher = {
bookName: 'book',
bookContent: 'hello world'
}
// 管家开始观测发布者
observer(publisher);
// 订阅者在平台上订阅发布者的部分信息
new Watcher(publisher, 'bookName', name => {
console.log(`new book name is ${name}`);
});
new Watcher(publisher, 'bookContent', content => {
console.log(`new book content is ${content}`);
});
// 发布者发布信息
publisher.bookName = 'new book';
publisher.bookContent = 'new content';