mitt@3.0.1源码阅读

8 阅读2分钟

mitt@3.0.1发布日期: 2023年7月5日

mitt 是一个超轻量(约 200 字节)、无依赖的 JavaScript 事件发射器 / 事件总线库,核心作用是实现发布 - 订阅模式,让不同模块、组件之间可以解耦通信,且不依赖任何前端框架(Vue/React/ 原生 JS 均可使用)。

mitt 有什么特点?

  • 极致轻量化:压缩后仅~200B,比 eventemitter3 更小,适合嵌入任何项目;
  • 无依赖:纯原生 JS 实现,不绑定任何框架,跨平台兼容;
  • API 极简on(订阅)、emit(发布)、off(取消订阅) 、all.clear(清除所有);
  • 支持 TypeScript:自带类型声明,类型提示友好;
  • 支持通配符:可以用 * 订阅所有事件,监听全局事件。

mitt

mitt-3.0.1/src/index.ts

function mitt<Events extends Record<EventType, unknown>>(
  all?: EventHandlerMap<Events>
): Emitter<Events> {
  
  type GenericEventHandler =
    | Handler<Events[keyof Events]>
    | WildcardHandler<Events>;
  
  all = all || new Map();

  return {
    all,
    // 注册事件处理器(订阅事件)。
    // type:事件类型(如 'click'),必须是 Events 中定义的键或通配符 *。
    // handler:事件触发时执行的函数。
    on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {
      // 从 all 映射表中获取该事件类型对应的处理器数组 handlers。
      const handlers: Array<GenericEventHandler> | undefined = all!.get(type);
      if (handlers) {
        // 若存在,则将新处理器 push 到数组中;
        handlers.push(handler);
      } else {
        // 若不存在,则初始化一个包含该处理器的数组并存入 all。
        all!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);
      }
    },

    // 移除事件处理器(取消订阅)。
    // type:事件类型。
    // handler(可选):要移除的具体处理器;若不传,则移除该事件类型的所有处理器。
    off<Key extends keyof Events>(type: Key, handler?: GenericEventHandler) {
      // 从 all 中获取该事件的处理器数组 handlers。
      const handlers: Array<GenericEventHandler> | undefined = all!.get(type);
      if (handlers) {
        if (handler) {
          // 若指定了 handler:通过 indexOf 找到索引,用 splice 移除(>>> 0 确保索引为非负数,避免 indexOf 返回 -1 时的错误)。          
          handlers.splice(handlers.indexOf(handler) >>> 0, 1);
        } else {
          // 若未指定 handler:直接将该事件的处理器数组设为空数组(清空所有处理器)。         
          all!.set(type, []);
        }
      }
    },
    // 触发事件(发布事件),执行该事件的所有处理器。
    // type:要触发的事件类型。
    // evt(可选):事件参数,类型需匹配 Events[Key]。
    emit<Key extends keyof Events>(type: Key, evt?: Events[Key]) {
      let handlers = all!.get(type);
      if (handlers) {
        // 从 all 中获取该事件的处理器数组 handlers,通过 slice() 复制一份
        // 遍历复制后的数组,依次执行每个处理器,并传入 evt 作为参数。
        (handlers as EventHandlerList<Events[keyof Events]>)
          .slice()
          .map((handler) => {
            handler(evt!);
          });
      }

      // 从 all 中获取 '*' 对应的处理器数组,同样复制后遍历执行。
      handlers = all!.get('*');
      if (handlers) {
        (handlers as WildCardEventHandlerList<Events>)
          .slice()
          .map((handler) => {
            handler(type, evt!);
          });
      }
    }
  };
}
interface Emitter<Events extends Record<EventType, unknown>> {
	all: EventHandlerMap<Events>;

	on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;
	on(type: '*', handler: WildcardHandler<Events>): void;

	off<Key extends keyof Events>(
		type: Key,
		handler?: Handler<Events[Key]>
	): void;
	off(type: '*', handler: WildcardHandler<Events>): void;

	emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;
	emit<Key extends keyof Events>(
		type: undefined extends Events[Key] ? Key : never
	): void;
}