设计模式-发布订阅模式(typescript版本)

原理:设计模式-观察者模式与发布订阅模式_观察者模式事件名-CSDN博客

实际操作:

interface EventCallback {
  context?: any;
  callback: (...args: any[]) => any;
}
export interface Event {
  on(eventName: string, callback: (...args: any[]) => any, context?: any, force?: boolean): Event;
  off(eventName: string, callback?: (...args: any[]) => any): Event;
  clear(): void;

  emit(eventName: string, data: any): boolean;
}

// call is faster than apply, optimize less than 3 argu
// http://blog.csdn.net/zhengyinhui100/article/details/7837127
function emitEvents(events: EventCallback[], args: any[], context?: any): void {
  if (args.length === 0) {
    for (const event of events) {
      event.callback.call(context || event.context);
    }
    return;
  }
  if (args.length <= 3) {
    for (const event of events) {
      event.callback.call(context || event.context, ...args);
    }
    return;
  }
  for (const event of events) {
    event.callback.apply(context || event.context, args);
  }
}
/**
 * example:
 * 订阅:
 * ObserverEvent.on(EventName,this.userInfo,this);
 * 发布:
 * ObserverEvent.emit(EventName,{userName:"小明",age:18,sex:"man"});
 * 取消订阅:
 * ObserverEvent.on(EventName,this.userInfo);
 */
export default class ObserverEvent {
  private static _eventMap: Map<string, EventCallback[]> = new Map<string, EventCallback[]>();
  private static _eventOnceMap: Map<string, EventCallback[]> = new Map<string, EventCallback[]>();
  /**
   * 注册回调
   * @param eventName  事件名
   * @param callback  回调函数
   * @param context 上下文
   * @returns
   */
  public static on(eventName: string, callback: (...args: any[]) => any, context?: any): Event {
    if (!this._eventMap.has(eventName)) this._eventMap.set(eventName, []);
    this._eventMap.get(eventName).push({
      callback,
      context,
    });
    return this;
  }
  /**
   * 删除回调,如果有callback则删除事件中指定回调,否则删除事件名的所有回调
   * @param eventName 事件名
   * @param callback 回调函数
   * @returns
   */
  public static off(eventName: string, callback?: (...args: any[]) => void): Event {
    if (!this._eventMap.has(eventName)) return this;
    if (!callback) {
      delete this._eventMap[eventName];
      return;
    }
    const events = this._eventMap.get(eventName);
    const index = events.findIndex((event) => event.callback === callback);
    if (events[index]) {
      events.splice(index, 1);
    }
    if (0 === events.length) delete this._eventMap[eventName];
    return this;
  }
  /**
   * 发布事件
   * @param eventName 事件名
   * @param args 参数
   * @returns
   */
  public static emit(eventName: string, ...args: any): boolean {
    if (!this._eventMap.has(eventName)) return false;
    const events = this._eventMap.get(eventName);
    emitEvents(events, args);
    return true;
  }
  /**
   * 注册一次性事件
   * @param eventName 事件名
   * @param callback 回调函数
   * @param context 上下文
   * @returns
   */
  public static onOnce(eventName: string, callback: (...args: any[]) => any, context?: any): Event {
    if (!this._eventOnceMap.has(eventName)) this._eventOnceMap.set(eventName, []);
    this._eventOnceMap.get(eventName).push({
      callback,
      context,
    });
    return this;
  }
  /**
   * 发布一次性事件
   * @param eventName
   * @param args
   * @returns
   */
  public static emitOnce(eventName: string, ...args: any): boolean {
    if (!this._eventOnceMap.has(eventName)) return false;
    const events = this._eventOnceMap.get(eventName);
    emitEvents(events, args);
    this._eventOnceMap.delete(eventName);
    return true;
  }
  /**
   *  删除一次性事件,如果有callback则删除事件中指定回调,否则删除事件名的所有回调
   * @param eventName
   * @param callback
   * @returns
   */
  public static offOnce(eventName: string, callback?: (...args: any[]) => void): Event {
    const eventMap = this._eventOnceMap;
    if (!eventMap.has(eventName)) return this;
    if (!callback) {
      eventMap.delete(eventName);
      return this;
    }
    const events = eventMap.get(eventName);
    const index = events.findIndex((event) => event.callback === callback);
    if (events[index]) {
      events.splice(index, 1);
    }
    if (0 === events.length) delete this._eventMap[eventName];
    return this;
  }

  public static clear(): void {
    this._eventMap.clear();
    this._eventOnceMap.clear();
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值