/** ***************************************** * Created by edonet@163.com * Created on 2021-03-22 22:32:16 ***************************************** */ 'use strict'; /** ***************************************** * 事件函数 ***************************************** */ type Handler = (state: T) => void; /** ***************************************** * 事件对象 ***************************************** */ interface Event { handler?: Handler; } /** ***************************************** * 订阅对象 ***************************************** */ export class Observer { /** 订阅列表 */ private $$observerList!: Event[]; /** 订阅数量 */ public get size(): number { // 过虑取消项 this.$$observerList = this.$$observerList.filter(ob => !!ob.handler); // 返回订阅数量 return this.$$observerList.length; } /** 初始化对象 */ public constructor() { Object.defineProperty(this, '$$observerList', { configurable: false, enumerable: false, writable: true, value: [], }); } /** 添加订阅 */ public subscribe(handler: Handler): () => void { const ob: Event = { handler }; // 校验参数 if (typeof handler !== 'function') { throw new Error('expect handler to be a function!'); } // 添加订阅 this.$$observerList.push(ob); // 返回取消函数 return () => ob.handler = undefined; } /** 通知订阅 */ public notify(state: T): void { const list = this.$$observerList; const result: Event[] = []; const len = list.length; // 遍历事件 for (let idx = 0; idx < list.length; idx ++) { const ob = list[idx]; // 执行回调 if (ob.handler) { // 添加监听 result.push(ob); // 执行回调 idx < len && ob.handler(state); } } // 更新列表 this.$$observerList = result; } /** 清空订阅 */ public clear(): void { this.$$observerList.forEach(ob => ob.handler = undefined); this.$$observerList = []; } } /** ***************************************** * 生成订阅对象 ***************************************** */ export function observer(): Observer { return new Observer(); }