/**
* 事件中心,用于跨组件/跨页面事件通信,详见 {@tutorial 2.8-eventHub}
*/
class EventHub {
_validEvents = []; //事件列表
_listeners = []; //监听列表
/**
* 构造函数
* @param {Array<string>} validEvents 配置的事件列表
*/
constructor({validEvents}){
if (!Array.isArray(validEvents)) {
console.error('[EventHub] bad param, validEvents shall be Array<string>');
return;
}
this._validEvents = validEvents;
}
/**
* 监听指定事件
* @param {string} eventType 事件类型
* @param {function} handler 监听函数
* @param {string} [persistType='once'] 持续策略:once-触发一次后自动移除监听 | always-每次都触发
*/
subscribe({eventType, handler, persistType='once'}){
if (!(this._validEvents.includes(eventType))) {
console.error('[EventHub] subscribe,试图监听无效事件:', eventType, '有效事件列表:', this._validEvents);
return;
}
this._listeners.push({
eventType,
handler,
triggerCount: 0, //触发了几次
limitCount: persistType==='once' ? 1 : 0, //最多触发几次,0表示不限
});
}
/**
* 触发指定事件
* @param {string} eventType 事件类型
* @param {*} data 传递给监听函数的数据
*/
notify({eventType, data}){
if (!(this._validEvents.includes(eventType))) {
console.error('[EventHub] notify,试图触发无效事件:', eventType, '有效事件列表:', this._validEvents);
return;
}
//监听回调
for (let listener of this._listeners) {
if (listener.eventType !== eventType)
continue;
try {
listener.handler(data);
} catch (e) {
console.error(
'[EventHub] caught err when exec handler',
'err:', e,
'eventType:', eventType,
'handler:', listener.handler
);
}
++ listener.triggerCount;
}
//移除达到回调上限的监听函数
this._listeners = this._listeners.filter(listener=>!(listener.limitCount>0 && listener.limitCount<=listener.triggerCount));
}
/**
* 取消监听
* @param {string} eventType 事件类型
* @param {function} handler 监听函数
*/
unsubscribe({eventType, handler}){
this._listeners = this._listeners.filter(listener=>!(listener.eventType===eventType && listener.handler===handler));
}
}
export default EventHub;