Files
2026-07-10 16:14:31 +08:00

173 lines
4.4 KiB
TypeScript

/**
* 优化后的事件系统
* 使用 WeakMap 来追踪监听器,避免内存泄漏
* 使用数组存储监听器,确保正确注册和移除
*/
export const customEvent = (function () {
let events: { [key: string]: any } = {};
// 用于追踪监听器的唯一标识,避免重复注册
let locked: { [key: string]: any } = {};
/**
* 检查监听器是否已经注册
*/
function isListenerRegistered(listeners: any, listener: any) {
if (!Array.isArray(listeners)) {
return false;
}
// 使用严格相等检查
return listeners.some(item => item === listener);
}
return {
/**
* 注册事件监听器
* @param {string} name - 事件名称
* @param {Function} callback - 回调函数
*/
on: function (name: string, callback: Function) {
if (typeof name !== 'string' || !name) {
return;
}
if (typeof callback !== 'function') {
return;
}
// 初始化事件数组
if (!events[name]) {
events[name] = [];
}
// 检查是否已经注册过
if (isListenerRegistered(events[name], callback)) {
return;
}
// 注册监听器
events[name].push({
once: false,
handler: callback
});
},
/**
* 注册事件监听器
* @param {string} name - 事件名称
* @param {Function} callback - 回调函数
*/
once: function (name: string, callback: Function) {
if (typeof name !== 'string' || !name) {
return;
}
if (typeof callback !== 'function') {
return;
}
// 初始化事件数组
if (!events[name]) {
events[name] = [];
}
// 检查是否已经注册过
if (isListenerRegistered(events[name], callback)) {
return;
}
// 注册监听器
events[name].push({
once: true,
handler: callback
});
},
/**
* 取消事件监听器
* @param {string} name - 事件名称
* @param {Function} callback - 要移除的回调函数,如果为 null 则移除该事件的所有监听器
*/
off: function (name: string, callback: null | Function = null) {
if (typeof name !== 'string' || !name) {
return;
}
// 如果事件不存在,直接返回
if (!events[name] || !Array.isArray(events[name])) {
return;
}
// 如果没有指定回调,移除该事件的所有监听器
if (callback === null) {
delete events[name];
return;
}
// 查找并移除指定的监听器
const index = events[name].findIndex((listener: { handler: Function }) => listener.handler === callback);
if (index !== -1) {
events[name].splice(index, 1);
}
// 如果该事件没有监听器了,清理事件对象
if (events[name].length === 0) {
delete events[name];
}
},
/**
* 触发事件
* @param {string} name - 事件名称
* @param {Object} data - 事件数据
*/
emmit: function (name: string, data: any) {
if (typeof name !== 'string' || !name) {
return;
}
// 如果事件不存在或没有监听器,直接返回
if (!events[name] || !Array.isArray(events[name]) || events[name].length === 0) {
return;
}
if ((locked[name] || false) === true) {
return;
}
locked[name] = true;
// 创建 SocketMessage 实例
// 复制监听器数组,避免在执行过程中数组被修改
const listeners = [...events[name]];
// 触发所有监听器
listeners.forEach((listener, index) => {
try {
if (listener.once) {
events[name].splice(index, 1)
}
listener.handler(data);
} catch (e) {
console.log(e)
}
});
locked[name] = false;
delete locked[name]
},
/**
* 获取事件监听器数量(用于调试)
* @param {string} name - 事件名称,如果为空则返回所有事件的信息
*/
getListenerCount: function (name: string) {
if (name) {
return events[name] ? events[name].length : 0;
}
const result: { [key: string]: any } = {};
Object.keys(events).forEach(eventName => {
result[eventName] = events[eventName].length;
});
return result;
}
}
})();