StateStore
函数签名
typescript
function StateStore() { ... }点击查看源码
js
/**
* 确保传入的方法只能被执行一次
*
* @param {(...args: any) => any} func - 要执行的方法。
* @returns {(...args: any) => any} 返回一个新的方法,该方法只会执行一次
*/
function once(fn) {
// 利用闭包判断函数是否执行过
let called = false;
return function (...args) {
if (!called) {
called = true;
return fn.apply(this, args);
}
};
}
/**
* 一个简单的事件发射器类,用于实现发布-订阅模式
*/
export class EventEmitter {
/** 存储所有事件及其对应的监听函数 */
events;
constructor() {
this.events = new Map();
}
/**
* 为指定事件添加监听器
* @param {string} eventName - 要监听的事件名称
* @param {Function} callback - 事件触发时要调用的回调函数
* @returns {Function} 返回一个用于取消订阅的函数
*/
on(eventName, callback) {
const callbacks = this.events.get(eventName) ?? [];
this.events.set(eventName, [...callbacks, callback]);
return () => once(this.off.bind(this))(eventName, callback);
}
/**
* 为指定事件添加一次性监听器,触发后自动移除
* @param {string} eventName - 要监听的事件名称
* @param {Function} callback - 事件触发时要调用的回调函数
* @returns {Function} 返回一个用于取消订阅的函数
*/
once(eventName, callback) {
const wrapper = (...args) => {
callback(...args);
this.off(eventName, wrapper);
};
return this.on(eventName, wrapper);
}
/**
* 移除指定事件的特定监听器
* @param {string} eventName - 事件名称
* @param {Function} callback - 要移除的监听器函数
*/
off(eventName, callback) {
const callbacks = this.events.get(eventName);
if (!callbacks) return;
const index = callbacks.indexOf(callback);
index !== -1 && callbacks.splice(index, 1);
callbacks.length === 0 && this.events.delete(eventName);
}
/**
* 移除指定事件的所有监听器,如果没有指定事件名称则移除所有事件的监听器
* @param {string} [eventName] - 可选的事件名称
*/
removeAllListeners(eventName) {
if (eventName) {
this.events.delete(eventName);
} else {
this.events.clear();
}
}
/**
* 触发指定事件,调用所有监听该事件的回调函数
* @param {string} eventName - 要触发的事件名称
* @param {...any} args - 传递给监听器的参数
*/
emit(eventName, ...args) {
const callbacks = this.events.get(eventName);
if (!callbacks) return;
// 创建回调函数数组的副本,防止回调函数中的操作影响遍历
const callbacksCopy = [...callbacks];
callbacksCopy.forEach((callback) => {
try {
callback(...args);
} catch (error) {
console.error(`Error in event handler for ${eventName}:`, error);
}
});
}
}
/*
* 状态管理存储类
* 用于管理应用状态并提供发布订阅功能
*/
export class StateStore {
state;
eventEmitter;
constructor() {
this.state = {};
this.eventEmitter = new EventEmitter();
}
/**
* 设置状态
* @param {keyof T} key - 状态键名
* @param {T[keyof T]} value - 状态值
*/
set(key, value) {
this.state[key] = value;
this.eventEmitter.emit(key, value);
}
/**
* 获取状态
* @param {keyof T | undefined} key - 状态键名,不传则返回整个状态对象
* @returns {T[keyof T] | T} 对应键的状态值或整个状态对象
*/
get(key) {
return key ? this.state[key] : this.state;
}
/**
* 订阅状态变化
* @param {keyof T} key - 要订阅的状态键名
* @param {(value: T[keyof T]) => void} callback - 状态变化时的回调函数
* @returns {() => void} 取消订阅的函数
*/
subscribe(key, callback) {
return this.eventEmitter.on(key, callback);
}
/**
* 取消订阅
* @param {keyof T} key - 要取消订阅的状态键名
* @param {(value: T[keyof T]) => void} callback - 之前注册的回调函数
*/
unsubscribe(key, callback) {
this.eventEmitter.off(key, callback);
}
/**
* 通知所有监听者
* @param {keyof T} key - 要通知的状态键名
* @param {T[keyof T]} value - 要传递的值
*/
notify(key, value) {
this.eventEmitter.emit(key, value);
}
/**
* 清空状态
*/
clear() {
this.state = {};
this.eventEmitter.removeAllListeners();
}
}ts
export type AnyFunction = (...args: any) => any;
/**
* 确保传入的方法只能被执行一次
*
* @param {(...args: any) => any} func - 要执行的方法。
* @returns {(...args: any) => any} 返回一个新的方法,该方法只会执行一次
*/
function once<F extends AnyFunction>(fn: F) {
// 利用闭包判断函数是否执行过
let called = false;
return function (this: unknown, ...args: Parameters<F>) {
if (!called) {
called = true;
return fn.apply(this, args);
}
};
}
/**
* 一个简单的事件发射器类,用于实现发布-订阅模式
*/
export class EventEmitter<T extends string> {
/** 存储所有事件及其对应的监听函数 */
private events: Map<T, AnyFunction[]>;
constructor() {
this.events = new Map();
}
/**
* 为指定事件添加监听器
* @param {string} eventName - 要监听的事件名称
* @param {Function} callback - 事件触发时要调用的回调函数
* @returns {Function} 返回一个用于取消订阅的函数
*/
on(eventName: T, callback: AnyFunction): () => void {
const callbacks = this.events.get(eventName) ?? [];
this.events.set(eventName, [...callbacks, callback]);
return () => once(this.off.bind(this))(eventName, callback);
}
/**
* 为指定事件添加一次性监听器,触发后自动移除
* @param {string} eventName - 要监听的事件名称
* @param {Function} callback - 事件触发时要调用的回调函数
* @returns {Function} 返回一个用于取消订阅的函数
*/
once(eventName: T, callback: AnyFunction): () => void {
const wrapper = (...args: any[]) => {
callback(...args);
this.off(eventName, wrapper);
};
return this.on(eventName, wrapper);
}
/**
* 移除指定事件的特定监听器
* @param {string} eventName - 事件名称
* @param {Function} callback - 要移除的监听器函数
*/
off(eventName: T, callback: AnyFunction): void {
const callbacks = this.events.get(eventName);
if (!callbacks) return;
const index = callbacks.indexOf(callback);
index !== -1 && callbacks.splice(index, 1);
callbacks.length === 0 && this.events.delete(eventName);
}
/**
* 移除指定事件的所有监听器,如果没有指定事件名称则移除所有事件的监听器
* @param {string} [eventName] - 可选的事件名称
*/
removeAllListeners(eventName?: T): void {
if (eventName) {
this.events.delete(eventName);
} else {
this.events.clear();
}
}
/**
* 触发指定事件,调用所有监听该事件的回调函数
* @param {string} eventName - 要触发的事件名称
* @param {...any} args - 传递给监听器的参数
*/
emit(eventName: T, ...args: any[]): void {
const callbacks = this.events.get(eventName);
if (!callbacks) return;
// 创建回调函数数组的副本,防止回调函数中的操作影响遍历
const callbacksCopy = [...callbacks];
callbacksCopy.forEach((callback) => {
try {
callback(...args);
} catch (error) {
console.error(`Error in event handler for ${eventName}:`, error);
}
});
}
}
/*
* 状态管理存储类
* 用于管理应用状态并提供发布订阅功能
*/
export class StateStore<T extends Record<string, any> = Record<string, any>> {
private state: T;
private eventEmitter: EventEmitter<string>;
constructor() {
this.state = {} as T;
this.eventEmitter = new EventEmitter<string>();
}
/**
* 设置状态
* @param {keyof T} key - 状态键名
* @param {T[keyof T]} value - 状态值
*/
set<K extends keyof T>(key: K, value: T[K]): void {
this.state[key] = value;
this.eventEmitter.emit(key as string, value);
}
/**
* 获取状态
* @param {keyof T | undefined} key - 状态键名,不传则返回整个状态对象
* @returns {T[keyof T] | T} 对应键的状态值或整个状态对象
*/
get<K extends keyof T>(key?: K): T[K] | T {
return key ? this.state[key] : this.state;
}
/**
* 订阅状态变化
* @param {keyof T} key - 要订阅的状态键名
* @param {(value: T[keyof T]) => void} callback - 状态变化时的回调函数
* @returns {() => void} 取消订阅的函数
*/
subscribe<K extends keyof T>(
key: K,
callback: (value: T[K]) => void,
): () => void {
return this.eventEmitter.on(key as string, callback);
}
/**
* 取消订阅
* @param {keyof T} key - 要取消订阅的状态键名
* @param {(value: T[keyof T]) => void} callback - 之前注册的回调函数
*/
unsubscribe<K extends keyof T>(
key: K,
callback: (value: T[K]) => void,
): void {
this.eventEmitter.off(key as string, callback);
}
/**
* 通知所有监听者
* @param {keyof T} key - 要通知的状态键名
* @param {T[keyof T]} value - 要传递的值
*/
notify<K extends keyof T>(key: K, value: T[K]): void {
this.eventEmitter.emit(key as string, value);
}
/**
* 清空状态
*/
clear(): void {
this.state = {} as T;
this.eventEmitter.removeAllListeners();
}
}如有错误,请提交issue :::