mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-09-19 03:55:50 +08:00
50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
import State from 'deep-state-observer';
|
||
|
||
import { ObservedData } from './ObservedData';
|
||
|
||
const ignoreFirstCall = <F extends (...args: any[]) => any>(fn: F) => {
|
||
let calledTimes = 0;
|
||
return (...args: Parameters<F>) => {
|
||
if (calledTimes === 0) {
|
||
calledTimes += 1;
|
||
return;
|
||
}
|
||
return fn(...args);
|
||
};
|
||
};
|
||
|
||
export class DeepObservedData extends ObservedData {
|
||
state?: State;
|
||
subscribers = new Map<string, Map<Function, () => void>>();
|
||
constructor(initialData: Record<string, any>) {
|
||
super();
|
||
this.state = new State(initialData);
|
||
}
|
||
update = (data: any, path?: string) => {
|
||
this.state?.update(path ?? '', data);
|
||
};
|
||
on = (path: string, callback: (newVal: any) => void, options?: { immediate?: boolean }) => {
|
||
// subscribe 会立即执行一次,ignoreFirstCall 会忽略第一次执行
|
||
const unsubscribe = this.state!.subscribe(path, options?.immediate ? callback : ignoreFirstCall(callback));
|
||
|
||
// 把取消监听的函数保存下来,供 off 时调用
|
||
const pathSubscribers = this.subscribers.get(path) ?? new Map<Function, () => void>();
|
||
pathSubscribers.set(callback, unsubscribe);
|
||
this.subscribers.set(path, pathSubscribers);
|
||
};
|
||
off = (path: string, callback: (newVal: any) => void) => {
|
||
const pathSubscribers = this.subscribers.get(path);
|
||
if (!pathSubscribers) return;
|
||
|
||
pathSubscribers.get(callback)?.();
|
||
pathSubscribers.delete(callback);
|
||
};
|
||
getData = (path: string) => (!this.state ? {} : this.state?.get(path));
|
||
destroy = () => {
|
||
// 销毁所有未被取消的监听
|
||
this.subscribers.forEach((pathSubscribers) => {
|
||
pathSubscribers.forEach((unsubscribe) => unsubscribe());
|
||
});
|
||
};
|
||
}
|