课程名称:2周刷完100道前端优质面试真题
课程章节:第8章 前端面试技能拼图6: 编写高质量代码 - 正确,完整,清晰,鲁棒
主讲老师:双越
课程内容:
今天学习的内容包括:
8-16 手写EventBus自定义事件-包括on和once
8-17 手写EventBus自定义事件-on和once分开存储
8-18 手写EventBus自定义事件-单元测试
课程收获:
API 操作:
on 同一个key,可绑定多个函数,依次执行。
once 同一个key,可绑定多个函数,依次执行,但只会触发一次。
emit 触发关键字,传参。
off 同一个key,可解绑某个或全部函数。
const e = new EventBus();
e.on('key1', fn2);
e.once('key1', fn3);
e.off('key1', fn1);
e.emit('key1', 10, 20);
API 实现思路:
整体用对象存储,key 对应数组,以执行函数对象 { fn, isOnce } 填充。
on 即往对应 key 数组添加执行函数对象。
once 同上,但要标记 isOnce: true
off 即找出 key 数组内对应函数对象删除或清空整个数组。
emit 找出 key 对应数组依次执行,并 filter isOnce为 true 的,重新赋值对应数组。
class EventBus {
constructor() {
this.events = {};
}
emit(type, ...arg) {
const fnList = this.events[type];
if (fnList == null) return;
this.events[type] = fnList.filter((item) => {
const { fn, isOnce } = item;
fn(...arg);
return !isOnce;
});
}
on(type, fn, isOnce = false) {
const events = this.events;
if (!events[type]) {
events[type] = [];
}
events[type].push({
fn,
isOnce,
});
}
once(type, fn) {
this.on(type, fn, true);
}
off(type, fn) {
if (fn) {
const fnList = this.events[type];
if (fnList && fnList.length) {
this.events[type] = fnList.filter((item) => item.fn !== fn);
}
} else {
this.events[type] = [];
}
}
}
以上,结束。