Created
October 6, 2017 14:09
-
-
Save leizongmin/9d4640a8310a1c4d52ce09005275928b to your computer and use it in GitHub Desktop.
简单的状态管理
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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