# 发布订阅模式
发布订阅模式,包含发布者,订阅者,事件调度中心3个角色.发布者和订阅者是松散耦合的,它们互不关心对方是否存在,它们关注的是事件本身 发布者通过事件调度中心提供的emit方法发布事件,订阅者则通过on方法订阅事件
class EventEmitter {
constructor() {
this.listeners = {};
}
/**
* @description:监听事件
* @param {*} type 事件类型
* @param {*} cb 触发函数
* @return {*}
*/
on(type, cb) {
if (!this.listeners[type]) {
this.listeners[type] = [];
}
this.listeners[type].push(cb);
}
/**
* @description: 发布事件
* @param {*} type 事件类型
* @param {array} args 触发函数参数
* @return {*}
*/
emit(type, ...args) {
if (this.listeners[type]) {
this.listeners[type].forEach((cb) => {
cb(...args);
});
}
}
/**
* @description: 移除某个事件的一个监听者
* @param {*} type
* @param {*} cb
* @return {*}
*/
off(type, cb) {
if (this.listeners[type]) {
let index = this.listeners[type].findIndex((item) => item === cb);
if (index !== -1) {
this.listeners[type].splice(index, 1);
}
if (this.listeners[type].length === 0) {
delete this.listeners[type];
}
}
}
/**
* @description: 移除某个事件所有监听者
* @param {*} type
* @return {*}
*/
offAll(type) {
if (this.listeners[type]) {
delete this.listeners[type];
}
}
}
/**
* @description: 发布-订阅模式
* @param {*}
* @return {*}
*/
class PubSub {
constructor() {
this.events = {};
}
/**
* @description: 订阅
* @param {*} type 事件类型
* @param {*} cb 回调函数
* @return {*}
*/
subscribe(type, cb) {
if (!this.events[type]) {
this.events[type] = [];
}
this.events[type].push(cb);
}
/**
* @description: 发布
* @param {*} type
* @param {array} args
* @return {*}
*/
publish(type, ...args) {
if (this.events[type]) {
this.events[type].forEach((cb) => {
cb(...args);
});
}
}
/**
* @description: 移除某个事件的一个订阅行为
* @param {*} type
* @param {*} cb
* @return {*}
*/
unsubscribe(type, cb) {
if (this.events[type]) {
let index = this.events[type].findIndex((item) => item === cb);
if (index !== -1) {
this.events[type].splice(index, 1);
}
if (this.events[type].length === 0) {
delete this.events[type];
}
}
}
/**
* @description: 移除某个事件的所有订阅行为
* @param {*} type
* @return {*}
*/
unsubscribeAll(type) {
if (this.events[type]) {
delete this.events[type];
}
}
}
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
vue的EventEmitter就是一个典型的订阅发布模式,发布者通过调度中心的emit方法发布事件,订阅者则通过on方法订阅事件
class EventEmitter {
constructor() {
this.listeners = {};
}
/**
* @description:监听事件
* @param {*} type 事件类型
* @param {*} cb 触发函数
* @return {*}
*/
on(type, cb) {
if (!this.listeners[type]) {
this.listeners[type] = [];
}
this.listeners[type].push(cb);
}
/**
* @description: 发布事件
* @param {*} type 事件类型
* @param {array} args 触发函数参数
* @return {*}
*/
emit(type, ...args) {
if (this.listeners[type]) {
this.listeners[type].forEach((cb) => {
cb(...args);
});
}
}
/**
* @description: 移除某个事件的一个监听者
* @param {*} type
* @param {*} cb
* @return {*}
*/
off(type, cb) {
if (this.listeners[type]) {
let index = this.listeners[type].findIndex((item) => item === cb);
if (index !== -1) {
this.listeners[type].splice(index, 1);
}
if (this.listeners[type].length === 0) {
delete this.listeners[type];
}
}
}
/**
* @description: 移除某个事件所有监听者
* @param {*} type
* @return {*}
*/
offAll(type) {
if (this.listeners[type]) {
delete this.listeners[type];
}
}
}
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
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
# 观察者模式
观察者模式与发布订阅模式相比,耦合度更高,通常用来实现一些响应式的效果。在观察者模式中,只有两个主体,分别是目标对象Subject,观察者Observer。
- 观察者需Observer要实现update方法,供目标对象调用。update方法中可以执行自定义的业务代码。
- 目标对象Subject也通常被叫做被观察者或主题,它的职能很单一,可以理解为,它只管理一种事件。Subject需要维护自身的观察者数组observerList,当自身发生变化时,通过调用自身的notify方法,依次通知每一个观察者执行update方法。
//观察者
class Observer {
constructor(cb) {
if (typeof cb !== 'function') {
throw new Error('Observer构造器必须传入函数类型!');
} else {
this.cb = cb;
}
}
update() {
this.cb();
}
}
//目标对象
class Subject {
constructor() {
// 维护观察者列表
this.observerList = [];
}
addObserver(observer) {
this.observerList.push(observer);
}
notify() {
this.observerList.forEach((observer) => {
observer.update();
});
}
}
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
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