-
-
Notifications
You must be signed in to change notification settings - Fork 98
/
event.js
101 lines (95 loc) · 2.24 KB
/
event.js
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
/*
* Author : OBKoro1
* Date : 2021-09-11 16:50:09
* LastEditors : OBKoro1
* LastEditTime : 2021-11-04 16:07:22
* FilePath : /js-base/src/scene/event.js
* description : 实现一个event类(订阅发布) 含有on off once emit方法
* koroFileheader VSCode插件
* Copyright (c) 2021 by OBKoro1, All Rights Reserved.
*/
// 订阅发布
class Event {
constructor() {
this.events = {}
}
// 订阅
on(type, fn) {
// 参数检测
if (!(fn instanceof Function)) {
throw '回调必须是函数'
}
// 初始化容器
if (!this.events[type]) {
this.events[type] = []
}
// 添加监听
if (!this.events[type].includes(fn)) {
this.events[type].push(fn)
}
}
/**
* description: 事件触发 通知所有订阅者
* param type [type] 事件类型
* param eventData [type] 事件信息 订阅者的数据
* param _this [type] 订阅者的this挂载
* return [type]
*/
emit(type, eventData, _this) {
if (!this.events[type]) {
throw '该事件未监听'
}
this.events[type].forEach((item) => {
item.call(_this, eventData)
})
}
// 取消订阅
off(type, fn) {
// 没有函数就清空
if (!fn) {
this.events[type] = []
return
}
// 使用filter 不使用splice 因为splice删除当前元素会影响当前emit遍历 导致事件触发不完整
this.events[type] = this.events[type].filter((item) => item !== fn)
}
// 订阅一次
once(type, fn) {
const self = this
// 重写函数
const reWriteFn = function (eventData) {
fn.call(this, eventData)
self.off(type, reWriteFn) // 执行后卸载
}
// 传入
this.on(type, reWriteFn)
}
}
// 测试代码
const e = new Event()
// 订阅
e.on('click', (msg) => {
console.log(1, msg, this)
})
function testOff(msg) {
console.log(2, msg, this)
}
e.on('click', testOff)
function fn3(msg) {
console.log(3, msg, this)
}
// 订阅一次
e.once('click', fn3)
function fn4(msg) {
console.log(4, msg, this)
}
e.once('click', fn4)
console.log(e)
// 通知事件更新
const obj = {
a: '传入的this对象',
}
e.emit('click', '事件数据', obj)
console.log(e)
e.off('click', testOff)
console.log('off取消订阅', e)