import { excludedInJSON } from '../decorators'; export type EventListener = (...args: Array) => any; export class EventEmitter { @excludedInJSON() private readonly _events: { [name: string]: Array } = {}; /** * 监听事件 * @param eventName 事件名 * @param listener 监听器 */ on(eventName: string, listener: EventListener) { let listeners = this._events[eventName]; if (!listeners) listeners = this._events[eventName] = []; const index = listeners.indexOf(listener); !~index && listeners.push(listener); } /** * 取消监听事件 * @param eventName 事件名 * @param listener 监听器 */ off(eventName: string, listener: EventListener) { const listeners = this._events[eventName]; if (listeners) { const index = listeners.indexOf(listener); ~index && listeners.splice(index, 1); } } /** * 只监听一次事件 * @param eventName 事件名 * @param listener 监听器 */ once(eventName: string, listener: EventListener) { const temp = (...args: Array) => { this.off(eventName, temp); listener.apply(this, args); }; this.on(eventName, temp); } /** * 触发事件 * @param eventName 事件名 * @param args 事件参数 */ emit(eventName: string, ...args: Array) { const listeners = this._events[eventName]; listeners && listeners.forEach((listener) => listener.apply(this, args)); } } export default EventEmitter;