UNPKG

mustard-app

Version:

个人前端微应用建设中。。。

142 lines (130 loc) 5.14 kB
import { IAppStatus, IAppStatusCN, MustardName } from '../typings'; import { isFunction } from '../utils/tools'; export type EventName = MustardName; // 用于区分子应用 export type BindMethod = string; export type TCallback = (value: unknown, oldValue:unknown, source:MustardName) => void; export type TLifeCallback = (key: MustardName) => void; export type TDataChangeCallback = (key: MustardName, data:unknown) => void; type EventGlobalLifeKey = `globalLife_${IAppStatusCN}`; // 全局生命周期key type EventGlobalDataChangeKey = 'globalDataChange'; // 全局prop修改key type EventDataKey = `data_${EventName}`; // prop注入key type EventDataChangeKey = `dataChange_${EventName}`; // prop修改key type EventLifeKey = `life_${EventName}_${IAppStatusCN}`; // 生命周期key type EventBindKey = `bind_${EventName}_${BindMethod}`; // 自定义事件key export type EventKey = |EventDataKey |EventDataChangeKey |EventLifeKey |EventBindKey |EventGlobalLifeKey |EventGlobalDataChangeKey; export interface EventValue { data: unknown, // 订阅的数据 sourceOfData: MustardName, // 数据的来源 assignment: boolean, // 是否已经赋值过 callbacks: Set<TCallback>, repeatSend: WeakSet<TCallback>, // 多次dispatch相同的data,只有第一次生效, 用于去重 } // 发布订阅系统中心 export class EventCenter { eventList : Map<EventKey, EventValue> = new Map(); /** * 初始化 * @param name 事件名 * @param options 事件配置 */ private initEvent (name:EventKey, options:Partial<EventValue> = {}) { this.eventList.set(name, { data: undefined, sourceOfData: undefined, assignment: false, callbacks: new Set(), repeatSend: new WeakSet(), ...options }); } /** * 订阅事件 * @param name 事件名 * @param fn 事件 * @param param2.immediately 是否立即执行(对应消息dispatch过) * @param param2.repeatSend 多次dispatch相同的data,只有第一次生效 */ on (name:EventKey, fn: TCallback, { immediately, repeatSend }:{immediately?: boolean, repeatSend?: boolean} = {}) { if(!isFunction(fn)) { return; } const events = this.eventList.get(name); if(!events) { this.initEvent(name, { callbacks: new Set([fn]), repeatSend: new WeakSet(repeatSend ? [fn] : []) }); }else{ events.callbacks.add(fn); repeatSend && events.repeatSend.add(fn); immediately && events.assignment && fn(events.data, undefined, events.sourceOfData); } } /** * 注销订阅事件 * @param name 事件名 * @param fn 事件 不传递全部清空 */ off (name:EventKey, fn?: TCallback) { const events = this.eventList.get(name); if(events) { fn ? events.callbacks.delete(fn) : events.callbacks.clear(); } } /** * 发布消息 * @param name 事件名 * @param source 那个应用发送的消息 * @param data 数据 */ dispatch (name:EventKey, source: MustardName, data?:unknown) { const events = this.eventList.get(name); const isSameData = events?.data === data; if(events) { const oldData = events.data; events.assignment = true; for (const callback of events.callbacks) { // 存在且值等于上一次不执行,其他的都执行 if(!(events.repeatSend.has(callback) && isSameData)) { callback(data, oldData, source); } } events.data = data; events.assignment = true; events.sourceOfData = source; }else{ this.initEvent(name, { data: data, sourceOfData: source, assignment: true, callbacks: new Set([]) }); } } } export function getEventGlobalLifeKeyByValue (value: IAppStatusCN):EventGlobalLifeKey { return `globalLife_${value}`; } export function getEventGlobalDataChangeKey ():EventGlobalDataChangeKey { return 'globalDataChange'; } export function getEventDataKey (name: EventName):EventDataKey { return `data_${name}`; } export function getEventDataChangeKey (name: EventName):EventDataChangeKey { return `dataChange_${name}`; } export function getEventLifeKeyByKey (name: EventName, key: IAppStatusCN):EventLifeKey { return `life_${name}_${key}`; } export function getEventLifeKeyByValue (name: EventName, value: IAppStatus):EventLifeKey { return `life_${name}_${IAppStatus[value]}` as EventLifeKey; } export function getEventBindKey (name: EventName, method: BindMethod):EventBindKey { return `bind_${name}_${method}`; }