EventBus 几个常用方法如下:
on |
发布和订阅 |
emit |
执行该订阅下的所有函数 |
off |
取消某个函数的订阅 |
once | 只执行一次订阅事件 |
这里用Map 存储 EventBus 的数据(发布者-订阅者)。
代码如下:
// 组件通信,一个触发与监听的过程
class EventBus {
constructor() {
this._events = new Map();//存储发布者和订阅者
}
on(type, fn) {//发布和订阅
//获取到该发布者下的订阅者集合handler
let handler = this._events.get(type);
//如果还没有订阅者
if (!handler) {
this._events.set(type, [fn]);//加入这个订阅者
} else {
handler.push(fn);//直接push进去handler
}
}
emit(type, ...args) {//执行该订阅下的所有函数
let handler = this._events.get(type);
for (let i = 0; i < handler.length; i++) {
handler[i].apply(this, args);//执行第i个订阅者函数
}
}
off(type, fn) {//取消某个函数的订阅
let handler = this._events.get(type);//获取所有的订阅者
//数组中订阅者有多个,找到等于fn的订阅者删除
handler.splice(handler.findIndex(e => e === fn), 1);
}
//只执行一次
once(type, fn) {
let _self = this;//拿到当前实例对象的this
function handler() {
_self.off(type, handler);//删除type下的handler函数
fn.apply(null, arguments);//执行该函数
}
this.on(type, handler)//type下添加handler函数
}
}
on |
发布和订阅。在type上添加订阅者。 |
emit |
执行该订阅下的所有函数。遍历type下的订阅者,执行。 |
off |
取消某个函数的订阅。在订阅者中找到fn然后删除。 |
once | once方法将handler函数挂载了type这个发布者上,如果执行emit就会执行handler函数中的内容,会先删除type上的所有的函数,然后执行fn。 |
测试代码:
//测试用例
// 下面是 测试代码
function test1(...params) {
console.log(11, params)
}
function test2(...params) {
console.log(22, params)
}
function test3(...params) {
console.log(33, params)
}
function test4(...params) {
console.log(44, params)
}
let eb = new EventBus()
//测试
eb.on('event1', test1)
eb.on('event1', test2)
eb.on('event1', test3)
eb.emit('event1', '第一次');//让挂载在event1下的所有test1,test2,test3全部执行
//输出11,'第一次' 22,'第一次' 33,'第一次'
//取消test1的订阅
eb.off('event1', test1)
eb.emit('event1', '第二次')//只输出test2,test3的结果
eb.once('once', test4);
eb.emit('once', '执行一次', 1, 2, 3)
eb.emit('once', '执行二次', 1, 2, 3)
结果:
结束!!