@logicflow/core
Version:
LogicFlow, help you quickly create flowcharts
157 lines (143 loc) • 4.13 kB
text/typescript
import { EventArgs } from './eventArgs'
export type EventType<T extends string = string> = {
readonly callback: EventCallback<T>
readonly once: boolean
}
export type EventsType<T extends string = string> = {
[k in T]?: EventType<k>[]
}
export type CallbackArgs<T extends string = string> = T extends keyof EventArgs
? EventArgs[T]
: // 如果不是内部定义的事件类型,那么允许用户抛出任何类型的参数
// 这部分的类型定义由用户自己来保证
any
export type EventCallback<T extends string = string> = (
args: CallbackArgs<T>,
) => void
const WILDCARD = '*'
/* event-emitter */
export default class EventEmitter {
private _events: EventsType = {}
/**
* 监听一个事件
* @param evt 事件名称
* @param callback 回调函数
* @param once 是否只监听一次
*/
on<T extends keyof EventArgs>(
evt: T,
callback: EventCallback<T>,
once?: boolean,
): void
on<T extends string>(evt: T, callback: EventCallback<T>, once?: boolean): void
on(evt: string, callback: EventCallback, once?: boolean) {
evt?.split(',').forEach((evKey) => {
evKey = evKey.trim()
if (!this._events[evKey]) {
this._events[evKey] = []
}
this._events[evKey]!.push({
callback,
once: !!once,
})
})
}
/**
* 监听一个事件一次
* @param evt 事件名称
* @param callback 回调函数
*/
once<T extends keyof EventArgs>(
evt: T,
callback: (args: EventArgs[T]) => void,
): void
once<T extends string>(evt: T, callback: EventCallback<T>): void
once(evt: string, callback: EventCallback) {
evt?.split(',').forEach((evKey) => {
evKey = evKey.trim()
this.on(evKey, callback, true)
})
}
/**
* 触发一个事件
* @param evts
* @param eventArgs
*/
emit<T extends keyof EventArgs>(evts: T, eventArgs: CallbackArgs<T>): void
emit<T extends string>(evts: T, eventArgs: CallbackArgs<T>): void
emit(evts: string, eventArgs?: EventCallback) {
evts?.split(',').forEach((evt) => {
const events = this._events[evt] || []
const wildcardEvents = this._events[WILDCARD] || []
// 实际的处理 emit 方法
const doEmit = (es: EventType[]) => {
let { length } = es
for (let i = 0; i < length; i++) {
if (!es[i]) {
continue
}
const { callback, once } = es[i]
if (once) {
es.splice(i, 1)
if (es.length === 0) {
delete this._events[evt]
}
length--
i--
}
callback.apply(this, [eventArgs])
}
}
doEmit(events)
doEmit(wildcardEvents)
})
}
/**
* 取消事件监听
* @param evts 事件名称
* @param callback 回调函数
*
* - evts 为空时,清除所有事件的监听器
* - evts 非空,callback 为空时,清除指定事件的所有监听器
* - evts 非空,callback 非空,进行对象比较,清除指定事件的指定监听器
*/
off<T extends keyof EventArgs>(
evts: T,
callback?: (args: EventArgs[T]) => void,
): void
off<T extends string>(evts: T, callback?: EventCallback<T>): void
off(evts: string, callback?: EventCallback) {
if (!evts) {
// evt 为空全部清除
this._events = {}
}
evts.split(',').forEach((evt) => {
if (!callback) {
// evt 存在,callback 为空,清除事件所有方法
delete this._events[evt]
} else {
// evt 存在,callback 存在,清除匹配的
const events = this._events[evt] || []
let { length } = events
for (let i = 0; i < length; i++) {
if (events[i].callback === callback) {
events.splice(i, 1)
length--
i--
}
}
if (events.length === 0) {
delete this._events[evt]
}
}
})
}
/* 当前所有的事件 */
getEvents() {
return this._events
}
destroy() {
this._events = {}
}
}
export { EventEmitter, EventArgs }