UNPKG

cross-magic

Version:

跨平台公共模块

149 lines (129 loc) 3.71 kB
type ListenerCell = { listener: Function thisObject: any priority: number } type ListenerMap = { [type: string]: Array<ListenerCell> } export type Event = { type: string data: any } /** * 事件发射器(发布订阅) */ export default class EventDispatcher { public static EVENT_MAX: number = 100 // 最多能监听100个事件 public static EVENT_CELL_MAX: number = 1000 // 同一个事件最多能添加1000个监听函数 private listenerMap: ListenerMap = {} /** * 注册监听事件 * 注意:注册监听函数时,会根据listener,thisObject来进行去重判断, * 当listener,thisObject都相同时,则会认为是同一个事件监听,不会将其注册进处理列表 * @param type 监听事件的类型 * @param listener 监听函数 * @param thisObject 监听函数的this指向 * @param priority 监听函数的优先级 */ addEventListener(type: string, listener: Function, thisObject: any, priority?: number) { if (!listener || !thisObject) { console.warn('EventDispatcher addEventListener listener or thisObject is null') return } const typeNum: number = Object.keys(this.listenerMap).length if (!this.listenerMap[type]) { if (!(typeNum >= EventDispatcher.EVENT_MAX)) { this.listenerMap[type] = [] this._insertEventListener(this.listenerMap[type], listener, thisObject, priority) } else { console.warn(`addEventListener eventtype overflow limit:${EventDispatcher.EVENT_MAX}`) } return } if (this.listenerMap[type].length >= EventDispatcher.EVENT_CELL_MAX) { console.warn( `addEventListener eventCellType overflow limit:${EventDispatcher.EVENT_CELL_MAX}` ) return } this._insertEventListener(this.listenerMap[type], listener, thisObject, priority) } /** * 移除监听函数 * @param type 事件类型 * @param listener 事件处理函数 * @param thisObject 事件处理函数this指向 */ removeEventListener(type: string, listener: Function, thisObject: any) { if (!type || !listener) { return } let list: Array<ListenerCell> = this.listenerMap[type] if (!list || list.length <= 0) { return } for (let i = list.length - 1; i >= 0; --i) { if (list[i].listener === listener && list[i].thisObject === thisObject) { list.splice(i, 1) break } } } /** * 触发事件 * @param event 事件数据 */ dispatchEvent(event: Event) { if (!event || !event.type) { console.log('dispatchEvent event is null') return } let eventList: Array<ListenerCell> = this.listenerMap[event.type] if (!eventList || eventList.length <= 0) { return } for (let i = 0; i < eventList.length; ++i) { if (eventList[i].listener) { eventList[i] } } } private _insertEventListener( list: Array<ListenerCell>, listener: Function, thisObject: any, priority?: number ) { if (priority) { priority = +priority | 0 } else { priority = 0 } let insertIndex = -1 for (let i = 0; i < list.length; ++i) { let cell: ListenerCell = list[i] if (cell.listener === listener && cell.thisObject === thisObject) { return false } if (insertIndex === -1 && priority > cell.priority) { insertIndex = i break } } if (insertIndex === -1) { list.push({ listener, thisObject, priority }) } else { list.splice(insertIndex, 0, { listener, thisObject, priority }) } return true } }