im-ui-mobile
Version:
A Vue3.0 + Typescript instant messaging component library for Uniapp
193 lines (172 loc) • 5.25 kB
JavaScript
/**
* 事件总线类
*/
class EventBus {
constructor() {
/**
* 存储事件和对应的回调函数列表
* @private
*/
this.events = new Map();
/**
* 存储全局监听器
* @private
*/
this.globalListeners = new Set();
}
/**
* 监听特定事件
* @param {string} eventName 事件名称
* @param {Function} callback 回调函数
*/
on(eventName, callback) {
if (typeof callback !== 'function') {
throw new Error('Callback must be a function');
}
if (!this.events.has(eventName)) {
this.events.set(eventName, new Set());
}
const callbacks = this.events.get(eventName);
callbacks.add(callback);
}
/**
* 监听所有事件
* @param {Function} callback 全局回调函数
*/
onAll(callback) {
if (typeof callback !== 'function') {
throw new Error('Callback must be a function');
}
this.globalListeners.add(callback);
}
/**
* 一次性监听特定事件
* @param {string} eventName 事件名称
* @param {Function} callback 回调函数
*/
once(eventName, callback) {
const onceCallback = (data) => {
callback(data);
this.off(eventName, onceCallback);
};
this.on(eventName, onceCallback);
}
/**
* 触发事件
* @param {string} eventName 事件名称
* @param {any} [data] 事件数据
*/
emit(eventName, data) {
// 调用全局监听器
this.globalListeners.forEach(callback => {
try {
callback(eventName, data);
} catch (error) {
console.error(`Global listener error for event "${eventName}":`, error);
}
});
// 调用特定事件的监听器
const callbacks = this.events.get(eventName);
if (callbacks) {
// 创建副本以避免在迭代过程中修改集合
const callbacksCopy = new Set(callbacks);
callbacksCopy.forEach(callback => {
try {
callback(data);
} catch (error) {
console.error(`Event listener error for "${eventName}":`, error);
}
});
}
}
/**
* 移除事件监听器
* @param {string} eventName 事件名称
* @param {Function} [callback] 要移除的回调函数(不传则移除所有监听器)
*/
off(eventName, callback) {
if (!this.events.has(eventName)) {
return;
}
const callbacks = this.events.get(eventName);
if (callback) {
// 移除特定的回调函数
callbacks.delete(callback);
// 如果该事件没有监听器了,删除事件
if (callbacks.size === 0) {
this.events.delete(eventName);
}
} else {
// 移除该事件的所有监听器
this.events.delete(eventName);
}
}
/**
* 移除所有事件监听器
*/
offAll() {
this.events.clear();
}
/**
* 移除全局监听器
* @param {Function} [callback] 要移除的全局回调函数(不传则移除所有全局监听器)
*/
offAllListener(callback) {
if (callback) {
this.globalListeners.delete(callback);
} else {
this.globalListeners.clear();
}
}
/**
* 获取事件监听器数量
* @param {string} [eventName] 事件名称(不传则返回所有事件的总数)
* @returns {number} 监听器数量
*/
getEventCount(eventName) {
if (eventName) {
const callbacks = this.events.get(eventName);
return callbacks ? callbacks.size : 0;
}
// 计算所有事件的监听器总数
let total = 0;
for (const callbacks of this.events.values()) {
total += callbacks.size;
}
return total;
}
/**
* 检查是否存在特定事件的监听器
* @param {string} eventName 事件名称
* @returns {boolean} 是否存在监听器
*/
hasEvent(eventName) {
return this.events.has(eventName) && this.events.get(eventName).size > 0;
}
/**
* 获取所有已注册的事件名称
* @returns {string[]} 事件名称数组
*/
getEventNames() {
return Array.from(this.events.keys());
}
/**
* 清空所有事件(包括全局监听器)
*/
clear() {
this.events.clear();
this.globalListeners.clear();
}
/**
* 销毁事件总线实例
*/
destroy() {
this.clear();
// 清空所有引用,帮助垃圾回收
this.events = null;
this.globalListeners = null;
}
}
const eventBus = new EventBus()
export { eventBus, EventBus }
export default eventBus