发布/订阅模式比较常用设计模式,今天给大家带来一个仅有200b的EventEmitter的mitt。
记录
export type EventType = string | symbol;
export type Handler<T = unknown> = (event: T) => void;
export type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<
keyof Events | '*',
EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>
>;
//记录所有订阅的事件
//key -> string, handler ->
//all 外部传入,类型 EventHandlerMap
all = all || new Map()
更多信息: typescript
订阅
export type WildcardHandler<T = Record<string, unknown>> = (
type: keyof T,
event: T[keyof T]
) => void;
type GenericEventHandler = | Handler<Events[keyof Events]> | WildcardHandler<Events>;
on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {
const handlers: Array<GenericEventHandler> | undefined = all!.get(type);
if (handlers) {
handlers.push(handler);
}else {
all!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);
}
},
on方法接受type和handler两个参数,其中接收一个订阅名称(type),和一个handler函数
取消订阅
off<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {
const handlers: Array<GenericEventHandler> | undefined = all!.get(type);
if (handlers) {
// 判断是否存在该handler,否则清空所有订阅type的事件
if (handler) {
handlers.splice(handlers.indexOf(handler) >>> 0, 1);
}
else {
all!.set(type, []);
}
}
},
off方法接受type和handler两个参数,其中接收一个订阅名称(type),和一个可选的handler函数,
发布
emit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {
// 通过type查看订阅type的事件
let handlers = all!.get(type);
if (handlers) {
(handlers as EventHandlerList<Events[keyof Events]>)
.slice()
.map((handler) => {
handler(evt!);
});
}
// 查找*(所有事件)
handlers = all!.get('*');
if (handlers) {
(handlers as WildCardEventHandlerList<Events>)
.slice()
.map((handler) => {
handler(type, evt!);
});
}
}
emit方法接受type和evt两个参数,其中接收一个订阅名称(type),和一个可选的evt参数,
结束
以上就是就是mitt的全部实现