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();
|