Skip to content

Instantly share code, notes, and snippets.

@leizongmin
Created October 6, 2017 14:09
Show Gist options
  • Save leizongmin/9d4640a8310a1c4d52ce09005275928b to your computer and use it in GitHub Desktop.
Save leizongmin/9d4640a8310a1c4d52ce09005275928b to your computer and use it in GitHub Desktop.
简单的状态管理
import * as immutable from 'immutable';
export type State = immutable.Map<string, any>;
export type Listener = () => void;
export const LISTENER_ALL = '@@@@ALL';
export class Store {
protected state: State;
protected listeners: Map<string, Listener[]> = new Map();
constructor(initialState: any = {}) {
this.state = immutable.fromJS(initialState);
}
public getState(): State {
return this.state.toJS();
}
public setState(state: any): void {
let callbacks: Listener[] = this.listeners.get(LISTENER_ALL) || [];
for (const name in state) {
this.state = this.state.set(name, state[name]);
const list = this.listeners.get(name);
if (Array.isArray(list)) {
callbacks = callbacks.concat(list);
}
}
if (callbacks.length > 0) {
const list = new Set(callbacks);
setImmediate(() => {
list.forEach(fn => fn());
});
}
}
public subscribe(callback: Listener): Subscriber {
return new Subscriber(this, callback);
}
public addListener(fields: string[], callback: Listener): void {
for (const name of fields) {
const list = this.listeners.get(name);
if (Array.isArray(list)) {
if (list.indexOf(callback) === -1) {
list.push(callback);
}
} else {
this.listeners.set(name, [callback]);
}
console.log(fields, callback, this);
}
}
public removeListener(fields: string[], callback: Listener): void {
for (const name of fields) {
const list = this.listeners.get(name);
if (Array.isArray(list)) {
const i = list.indexOf(callback);
if (i !== -1) {
list.splice(i, 1);
}
}
}
}
}
export class Subscriber {
public listening: boolean = false;
private fields: string[];
constructor(private store: Store, private callback: Listener) { }
public for(...fields: string[]): this {
this.fields = fields;
return this.subscribe();
}
public all(): this {
this.fields = [ LISTENER_ALL ];
return this.subscribe();
}
private subscribe(): this {
this.store.addListener(this.fields, this.callback);
this.listening = true;
return this;
}
public unsubscribe(): void {
this.store.removeListener(this.fields, this.callback);
delete this.store;
delete this.callback;
delete this.fields;
delete this.listening;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment