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
interface List {
[key:string]:Array<Function>
}
interface EventType{
list:List
on:(name:string,fn:Function)=>void
emit:(name:string,...args:any)=>void
once:(name:string,fn:Function)=>void
off:(name:string,fn:Function)=>void
}

class Event implements EventType{
list:List = {}
constructor() {
this.list = {}
}
on(name:string,fn:Function){
let funArr = this.list[name] || []
funArr.push(fn)
this.list[name] = funArr
}
emit(name:string,...args:Array<any>){
let funArr = this.list[name]
if(funArr){
funArr.forEach(fn=>fn.apply(this,args))
}else{
console.log('未找到注册的函数名')
}
}
once(name:string,fn:Function){
let tmpFn = (...args:Array<any>)=>{
fn.apply(args)
this.off(name,tmpFn)
}
this.on(name,tmpFn)
}
off(name:string,fn:Function){
let funArr = this.list[name]
if(funArr){
let index = funArr.findIndex(singleFn=>singleFn===fn)
if(index>=0){
funArr.splice(index,1)
this.list[name] = funArr
console.log('删除成功')
}else{
console.log('未找到要删除的函数')
}
}else{
console.log('未找到注册的函数名')
}
}
}

需要注意的是,在off方法中比较函数是否相等,比较的是函数的地址,如果是订阅的是匿名函数将无法删除,因为匿名函数的地址是不同的,在订阅的时候应该使用命名函数。