-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathEventEmitter.js
More file actions
130 lines (106 loc) · 3.03 KB
/
Copy pathEventEmitter.js
File metadata and controls
130 lines (106 loc) · 3.03 KB
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
121
122
123
124
125
126
127
128
129
130
class EventEmitter {
constructor () {
/**
* 以 key-value 形式存储事件类型和对应的处理函数,value 为数组,存放多个事件处理函数
* Object.create(null) 创建的空对象不会有原型,非常纯净,当某些库修改了 Object 的原型后也不会受影响,但是 Object.create({}) 就有原型了
*/
this.events = Object.create(null)
this.maxHandlerCount = 10 // 允许注册的单个事件类型的最多事件处理函数数量
}
/**
* 事件监听
* @param {string} type 事件类型
* @param {function} handler 事件处理函数
*/
on (type, handler) {
if (!this.events[type]) {
this.events[type] = [] // 一个事件类型可以注册多个处理函数
}
this.events[type].push(handler)
}
/**
* once 是监听后只执行一次,本质是定义一个包装函数,通过 on 去监听包装函数。当在包装函数里把传递进来的处理函数执行完后,包装函数移除在 on 上监听的包装函数
* @param {string} type 事件类型
* @param {function} handler 事件处理函数
*/
once (type, handler) {
var _self = this
function wrapper () {
handler.apply(this, arguments)
_self.off(type, wrapper)
}
this.on(type, wrapper)
return this
}
/**
* 事件触发
* @param {string} type 事件类型
* @param {...any} args 参数
*/
emit (type, ...args) {
const event = this.events[type]
/**
* 依次执行注册过的事件类型对应的所有处理函数
*/
if (event) {
for (var i = 0; i < event.length; i++) {
event[i](...args)
}
}
return this
}
/**
* 移除事件监听
* @param {string} type 事件类型
* @param {function} handler 事件处理函数
*/
off (type, handler) {
const handlers = this.events[type]
if (handlers && handlers.length) {
const index = handlers.indexOf(handler)
if (index > -1) {
handlers.splice(index, 1)
}
}
}
/**
* 设置某类型事件的处理函数的最大值
* @param {number} len
*/
setHandlerLength (len = 10) {
this.maxHandlerCount = len
}
/**
* 清除所有事件监听
*/
destroy () {
this.events = {}
}
}
const eventEmitter = new EventEmitter()
var i = 1
// 1. test click handler
eventEmitter.on('click', (params) => {
console.log('i am clicked ===', params)
})
eventEmitter.emit('click', 'access params to click handler')
// 2. test off scrollHandler
function scrollHandler (params) {
console.log('params ===', params, i++)
}
eventEmitter.on('scroll', scrollHandler)
eventEmitter.emit('scroll', 'i am canceled')
eventEmitter.emit('scroll', 'i am canceled')
eventEmitter.off('scroll', scrollHandler)
eventEmitter.emit('scroll', 'i am canceled')
// 3. test once
i = 1
function touchHandler () {
console.log('touched', i++)
}
eventEmitter.once('touch', touchHandler)
eventEmitter.emit('touch')
eventEmitter.emit('touch')
eventEmitter.emit('touch')
eventEmitter.destroy()
console.log(eventEmitter)