Last active
February 20, 2018 08:11
-
-
Save kkoziarski/4d8482ac90048451ac94183ea7befdf3 to your computer and use it in GitHub Desktop.
Subscribe with unsubscribe listeners
This file contains hidden or 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
// https://github.com/ng-book/angular2-redux-chat/blob/master/tutorial/06b-rx-store.ts | |
import { BehaviorSubject } from 'rxjs/BehaviorSubject'; | |
import { Subject } from 'rxjs/Subject'; | |
import 'rxjs/add/operator/scan'; | |
interface Action { | |
type: string; | |
payload?: any; | |
} | |
class Store<T> extends BehaviorSubject<T> { | |
private _dispatcher: Subject<Action>; | |
constructor( | |
initialState: T | |
) { | |
super(initialState); | |
this._dispatcher = new Subject<Action>(); | |
this._dispatcher | |
.scan( | |
(state: T, action: Action) => /*TODO: this._reducer(state, action)*/, | |
initialState) | |
.subscribe((state) => super.emit(state)); | |
} | |
getState(): T { | |
return this.value; | |
} | |
dispatch(action: Action): void { | |
this._dispatcher.emit(action); | |
} | |
} | |
// create a new store | |
console.log('-- store --'); | |
let store = new Store<number>(0); | |
console.log(store.getState()); // -> 0 | |
store.dispatch({ type: 'INCREMENT' }); | |
console.log(store.getState()); // -> 1 | |
store.dispatch({ type: 'INCREMENT' }); | |
console.log(store.getState()); // -> 2 | |
store.dispatch({ type: 'DECREMENT' }); | |
console.log(store.getState()); // -> 1 | |
// observing! | |
console.log('-- store2 --'); | |
let store2 = new Store<number>(0); | |
store2.subscribe((newState => console.log("state: ", newState))); // -> state: 0 | |
store2.dispatch({ type: 'INCREMENT' }); // -> state: 1 | |
store2.dispatch({ type: 'INCREMENT' }); // -> state: 2 | |
store2.dispatch({ type: 'DECREMENT' }); // -> state: 1 |
This file contains hidden or 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
// https://github.com/ng-book/angular2-redux-chat/blob/master/tutorial/05-minimal-store.ts | |
interface Action { | |
type: string; | |
payload?: any; | |
} | |
interface ListenerCallback { | |
(): void; | |
} | |
interface UnsubscribeCallback { | |
(): void; | |
} | |
class Store<T> { | |
private _state: T; | |
private _listeners: ListenerCallback[] = []; | |
constructor( | |
initialState: T | |
) { | |
this._state = initialState; | |
} | |
getState(): T { | |
return this._state; | |
} | |
dispatch(action: Action): void { | |
// do something on this._state... | |
// ...then call listeners | |
this._listeners.forEach((listener: ListenerCallback) => listener()); | |
} | |
subscribe(listener: ListenerCallback): UnsubscribeCallback { | |
this._listeners.push(listener); | |
return () => { // returns an "unsubscribe" function | |
this._listeners = this._listeners.filter(l => l !== listener); | |
}; | |
} | |
} | |
// create a new store | |
let store = new Store<number>(0); | |
console.log(store.getState()); // -> 0 | |
// subscribe | |
let unsubscribe = store.subscribe(() => { | |
console.log('subscribed: ', store.getState()); | |
}); | |
store.dispatch({ type: 'INCREMENT' }); // -> subscribed: 1 | |
store.dispatch({ type: 'INCREMENT' }); // -> subscribed: 2 | |
unsubscribe(); | |
store.dispatch({ type: 'DECREMENT' }); // (nothing logged) | |
// decrement happened, even though we weren't listening for it | |
console.log(store.getState()); // -> 1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment