使用js简单模拟事件总线的处理机制,包括on,once,off,emit四个方法
class EventEmitter {
constructor() {
this.events = {}
}
//key存在时,只需要把回调加入数组,不存在时,需要创建该key对应的值
on(key, callback) {
if (Object.keys(this.events).includes(key)) {
this.events[key].push(callback)
} else {
this.events[key] = [callback]
}
}
//使用once绑定时,执行后需关闭该事件监听
once(key, callback) {
let that = this
const handler = function (...args) {
callback.apply(null, args)
that.off(key, handler)
}
if (Object.keys(this.events).includes(key)) {
this.events[key].push(handler)
} else {
this.events[key] = [handler]
}
}
//该事件存在回调时,移除该回调然后检测是否需要删除key,不存在时,直接移除该key
off(key, callback) {
let callbacks = this.events[key]
if (callbacks && callbacks.length) {
let index = callbacks.indexOf(callback)
if (index > -1) {
this.events[key].splice(index, 1)
if (!callbacks.length) {
delete this.events[key]
}
}
} else {
delete this.events[key]
}
}
//该事件存在回调时,依次执行回调
emit(key, ...args) {
let callbacks = this.events[key]
if (callbacks && callbacks.length) {
callbacks.forEach(element => {
element.apply(null, args)
});
}
}
}
export default EventEmitter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script type="module">
import EventEmitter from './index.js'
let event = new EventEmitter()
event.on('test', test1)
event.on('test', test2)
event.emit('test', 111, 222)
event.off('test', test1)
//test1事件关闭之后3秒后只执行test2
setTimeout(() => {
event.emit('test', 111, 222)
}, 3000);
function test1(data1, data2) {
console.log(data1)
console.log(data2)
}
function test2(data1, data2) {
console.log(data1+data2)
}
</script>
</body>
</html>