liaolx
2026-01-28 800921d1019814acce308db825662cdb3878842c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import globalState from "./global-state";
 
interface FunctionList {
  [propName : string] : Array<Function>,
}
 
interface SubscriberMap {
  [propName : string] : Array<number>,
}
 
export class ObserverClass {
  private funcList: FunctionList;
  private funcMap: any;
  private subscriberMap: SubscriberMap;
 
  constructor() {
    this.funcList = {};
    this.funcMap = {};
    this.subscriberMap = {};
  }
  // 注册特殊的标记到订阅者池
  registerAsSubscriber(name: string) {
    if (!this.subscriberMap[name]) this.subscriberMap[name] = [];
  }
  // 批量释放订阅者池的监听器
  removeEventListenerInBatch(subscriberName: string) {
    if (!this.subscriberMap[subscriberName]) return;
    while (this.subscriberMap[subscriberName].length) {
      const index = this.subscriberMap[subscriberName].pop();
      this.removeEventListener(index || -1);
    }
  }
 
  addEventListener(name: string, func: Function, subscriberName?: string) {
    if (!this.funcList[name]) this.funcList[name] = [];
    if (typeof func === 'function') {
      this.funcList[name].push(func);
      const randomIndex = Math.round(Math.random() * 1000000);
      this.funcMap[randomIndex] = { name, index: this.funcList[name].length - 1 };
      if (subscriberName && this.subscriberMap[subscriberName]) this.subscriberMap[subscriberName].push(randomIndex);
      return randomIndex;
    }
    return 0;
  }
 
  removeEventListener(randomIndex: number) {
    if (!Object.hasOwnProperty.call(this.funcMap, randomIndex)) return;
    const info = this.funcMap[randomIndex];
    this.funcList[info.name].splice(info.index, 1);
    delete this.funcMap[randomIndex];
  }
  /**
   * 对全局派发一个事件,返回一个布尔值标记是否有订阅者响应事件
   * @param name 事件名称
   * @param arg 事件参数
   */
  dispatchEvent(name: string, arg?: any): boolean {
    let hasBeenResponse = false;
    const currentPage = globalState.getState('currentPage', {
      context: {},
      id: -1,
    });
    const { context } = currentPage;
    if (typeof context[name] === 'function') {
      // 异步执行
      setTimeout(() => {
        context[name].bind(context)(arg);
      }, 0);
      hasBeenResponse = true;
    }
    if (this.funcList[name] && this.funcList[name].length) {
      this.funcList[name].forEach((ele: Function) => {
        // 异步执行
        setTimeout(() => ele(arg), 0);
      });
      hasBeenResponse = true;
    }
    return hasBeenResponse;
  }
}
 
export default new ObserverClass();