/** * 优化后的事件系统 * 使用 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; } } })();