# 观察者
允许你制定一种订阅机制, 可在对象事件发生时通知多个 "观察" 该对象的其他对象
# 优点
开闭原则 无需修改发布者代码就能引入新的订阅者类
可在运行时建立对象之间的联系
# 缺点
- 订阅者的通知顺序是随机的
# 适用场景
当一个对象状态的改变需要改变其他对象, 或实际对象是事先未知的或动态变化的时
例如你创建了自定义按钮类并允许客户端在按钮中注入自定义代码, 这样当用户按下按钮时就会触发这些代码
当应用中的一些对象必须观察其他对象时, 可使用该模式, 但仅能在有限时间内或特定的情况下使用
# 发布订阅实现
点击查看代码
/**
* 发布订阅
*/
class Emitter {
constructor() {
this.emits = {}
}
on(emitName, callback) {
if (!this.emits[emitName]) {
this.emits[emitName] = []
}
if (this.emits[emitName].includes(callback)) {
// 事件重复注册
console.log(`${emitName} 事件重复注册!`)
} else {
this.emits[emitName].push({
handler: callback
})
}
}
once(emitName, callback) {
if (!this.emits[emitName]) {
this.emits[emitName] = []
}
this.emits[emitName].push({
handler: callback,
once: true
})
}
emit(emitName, ...args) {
if (!this.emits[emitName]) return
this.emits[emitName].forEach((item, index) => {
item.handler(...args)
if (item.once) {
this.emits[emitName].splice(index, 1)
}
})
}
off(emitName, callback) {
if (this.emits[emitName]) {
if (
callback &&
callback instanceof Function &&
this.emits[emitName].includes(callback)
) {
this.emits[emitName] = this.emits[emitName].filter(v => v.handler !== callback)
} else {
delete this.emits[emitName]
}
}
}
}
// ---------- Test ---------
const emitter = new Emitter()
function user1(content) {
console.log('user1 on', content)
}
function user2(content) {
console.log('user2 on', content)
}
emitter.on('test', testHandle)
emitter.on('test2', test2Handle)
emitter.emit('test', 'emit...') // user1 on emit...
emitter.emit('test2', 'emit2...') // user2 on emit2...
emitter.off('test', testHandle)
emitter.emit('test', testHandle) // no output
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
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