手写订阅与发布模式

对象方式

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
const eventHub = {
map: {
//haspMap
// click: [f1 , f2]
},
on: (name, fn) => {
eventHub.map[name] = eventHub.map[name] || []; //设计模式:防御性编程,避免eventHub.map[name]不存在
eventHub.map[name].push(fn);
},
emit: (name, data) => {
const q = eventHub.map[name]; //设计模式:Alias 别名
if (!q) return;
q.forEach((f) => f.call(null, data));
return undefined;
},
off: (name, fn) => {
const q = eventHub.map[name]; //设计模式:Alias 别名
if (!q) {
return;
}
const index = q.indexOf(fn);
if (index < 0) {
return;
}
q.splice(index, 1);
},
};

使用示例如下:

1
2
3
4
5
6
eventHub.on('click', console.log);
eventHub.on('click', console.error);

setTimeout(() => {
eventHub.emit('click', 'frank');
}, 3000);

class 方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class EventHub {
map = {};
on(name, fn) {
this.map[name] = this.map[name] || [];
this.map[name].push(fn);
}
emit(name, data) {
const fnList = this.map[name] || [];
fnList.forEach((fn) => fn.call(undefined, data));
}
off(name, fn) {
const fnList = this.map[name] || [];
const index = fnList.indexOf(fn);
if (index < 0) return fnList.splice(index, 1);
}
}

使用示例如下:

1
2
3
4
5
6
7
8
9
10
11
// 使 用 const e = new EventHub()

e.on('click', (name) => {
console.log('hi ' + name);
});
e.on('click', (name) => {
console.log('hello ' + name);
});
setTimeout(() => {
e.emit('click', 'frank');
}, 3000);

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!