EventBus 探索 (JS)
EventBus 用来管理事件的发布与订阅,在 Android 届非常有名气,可以简化系统提供的事件通信,比如 Handler, BoardCast 等。JS 里面,没有提供原生的事件管理机制的支持,但对于模块很多的页面,采用事件来管理无疑是一个很好的选择,所以,在 Github 上撸了一个 JS 版的 EventBus 库,源码真是精简,总共一个文件,100 行,本文就以一个小白的角度,梳理一下这个库。
场景
当一个页面中,有多个模块,就比如这个博客页面,每个菜单按钮都对应于一个模块,传统的做法,在按钮的点击事件里,处理各个模块的逻辑,同时或许还要处理其他模块的显示隐藏清空等逻辑。
1 | menu.about.click = function() { |
如果页面模块不多,这样做完全是 ok 的,但假使要增加一个模块,就需要在上面的方法里额外在增加一些判断逻辑代码,这样有一个缺点,就是代码耦合比较紧,而使用事件就可以解决这个问题,点击菜单的时候,发送一个唯一的事件,在监听这个事件的方法里,实现对事件的处理。
1 | menu.about.dispatch("aboutBtnClicked"); |
可以看到,点击菜单按钮,不做任何逻辑,仅仅是发送了一个事件通知,具体的业务逻辑交由页面各个模块自己处理。只需要知道是哪个事件即可。
特性
Eventbus 库非常精简,它仅有以下 5 个方法。
- addEventListener(type, callback, scope) — 添加一个事件监听
- removeEventListener(type, callback, scope) — 移除一个事件监听
- dispatch(type, target) — 发布一个事件
- getEvents() — 调试使用,仅仅打印添加的监听
- hasEventListener() — 判断是否有事件监听
例子
假使现在一个页面有三个 tab,点击每一个 tab 切换一个页面,用事件通知来处理 tab 切换。
定义事件类型 & 事件监听器
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
26onLoad() {
eventbus.addEventListener('clickTab_1', clickTab_1, this);
eventbus.addEventListener('clickTab_2', clickTab_2, this);
eventbus.addEventListener('clickTab_3', clickTab_3, this);
function clickTab_1(event) {
console.log('type=' + event.type);
this.showTab1 = true;
this.showTab2 = false;
this.showTab3 = false;
};
function clickTab_2(event) {
console.log('type=' + event.type);
this.showTab1 = false;
this.showTab2 = true;
this.showTab3 = false;
};
function clickTab_3(event) {
console.log('type=' + event.type);
this.showTab1 = false;
this.showTab2 = false;
this.showTab3 = true;
};
};点击时发送事件
1
2
3
4
5
6
7
8
9
10clickTab(index) {
const tabIndex = index - 0;
if (tabIndex === 1) {
eventbus.dispatch('clickTab_1');
} else if (tabIndex === 2) {
eventbus.dispatch('clickTab_2');
} else if (tabIndex === 3) {
eventbus.dispatch('clickTab_3');
}
},
对象传递
上面的例子中,eventbus.dispatch(‘eventName’) 方法仅仅是发送了一个事件类型,看下源码,dispatch 可以接受两个参数,第一个事件类型,第二个就是当前对象,也就是说,dispatch 可以传递对象,这样一来,页面即使有很多对象,引用起来也很方便了。
需要注意的是,当想要获取到对象的属性时,eventbus.addEventListener(type, callback, scope) 方法一定要传 scope 参数,给个 this,表示当前类的作用域。
每个监听器的回调函数里面都接受一个 event 对象,包含两个属性:
- type — 发布事件的名称
- target — dispatch 对象(如果有)
多参数传递
EventBus 支持传递多参数,在 dispatch( type, target) 方法中,如果方法传入超过 2 个参数,2个之后的都作为参数,在 addEventListener() 的回调方法中,可以获取到。
1 | EventBus.dispatch("custom_event", this, "javascript events", " are really useful"); |
EventBus 所有的功能基本就是以上这些,建议大家去读一下源码,了解开源者的设计思想。
Title: EventBus 探索 (JS)
Author: mjd507
Date: 2017-08-20
Last Update: 2024-01-27
Blog Link: https://mjd507.github.io/2017/08/20/Reading-EventBus-JS/
Copyright Declaration: This station is mainly used to sort out incomprehensible knowledge. I have not fully mastered most of the content. Please refer carefully.