// 使用一个对象来管理所有的事件和处理程序
// 优点:有效地降低消息发布者和订阅者之间的耦合度
function EventBus() {
this._eventBus = {};
}
EventBus.prototype = {
constructor: EventBus,
isStrValid(str) {
return str && Object.prototype.toString.call(str) === '[object String]';
},
// 监听
$on(eventName, fn) {
if (!this.isStrValid(eventName)) {
console.error('请传入正确的事件名称');
return;
}
let eventBus = this._eventBus,
handlers = eventBus[eventName];
if (!handlers) {
eventBus[eventName] = [fn];
return;
}
if (handlers.includes(fn)) {
return;
}
handlers.push(fn);
},
// fn只执行一次
$once(eventName, fn) {
let that = this;
let onceFn = function () {
fn(...arguments);
that.$off(eventName, onceFn);
};
this.$on(eventName, onceFn);
},
// 触发
$fire(eventName, ...args) {
if (!this.isStrValid(eventName)) {
console.error('请传入正确的事件名称');
return;
}
let arrHandler = this._eventBus[eventName];
if (!arrHandler || !arrHandler.length) {
return;
}
arrHandler.forEach(fn => {
fn(...args);
});
},
// 解绑
$off(eventName, ...fns) {
if (!arguments.length) {
// 解绑所有事件
this._eventBus = {};
return;
}
if (!this.isStrValid(eventName)) {
console.error('请传入正确的事件名称');
return;
}
if (!fns.length) {
// 解绑所有的eventName事件
delete this._eventBus[eventName];
return;
}
// 解绑fns
let handlers = this._eventBus[eventName];
this._eventBus[eventName] = handlers.filter(fn => !fns.includes(fn));
},
};
网友评论