StateStream

constructor:

  • constructor(streamName: string, initialValue?: any, stateStreams?: Array<StateStream>)

public properties:

  • state$
  • streamName
  • emitters

public methods:

  • emitter
  • getState
  • next
  • eventRunner
  • dispose

StateStream is a core class in Rxact, it is convenient that using StateStream to manage state and logic. Before using Rxact, you can image your application logic as multiple logic streams, then expressing them through StateStream.

Example

1.create a simple StateStream

const stateStream = new StateStream('example', {})

A simple example for creating a state stream with name 'example' and initial state '{}'.

2.create more state streams, and combine them together.

const userStream = new StateStream('users', [{ id: 1, name: 'darmody' }, { id: 2, name: 'john' }]) 
const postStream = new StateStream('posts', [{ id: 1, title: 'API Overview' }, { id: 2, title: 'README' }]
const appStream = new StateStream('app', { currentUserId: 1, currentPostId: 1 }, [userStream, postStream])

appStream.state$.subscribe(state => console.log(state))
// {
//   app: { currentUserId: 1, currentPostId: 1 },
//   users: [{ id: 1, name: 'darmody' }, { id: 2, name: 'john' }],
//   posts: [{ id: 1, title: 'API Overview' }, { id: 2, title: 'README' }]
// }

You can see that it is easy to combine state and logic through StateStream for managing complex logic.

state$

state$ is an observable object of state. You can call operators defined by the lib you used, and subscribe it.

Example

const stream = new StateStream('example', 0)

const subscription1 = stream.state$.subscribe(state => console.log('sub1', state))
// subscribe will output current value immediately, it is initial value here.

stream.next(() => 1)
// update state to 1

const subscription2 = stream.state$.subscribe(state => console.log('sub2', state))
// output current value which is 1

// console.log output:
// sub1 0
// sub1 1
// sub2 2

Note: next is an asynchronous operator, it looks like synchronization in example just for demonstrating.

streamName

streamName is name of the stream.

Example

const stream = new StateStream('example')

console.log(stream.streamName)
// example

emitters

emitters is an Object whose each key mapping to a state updating operator defined by emitter. You don't need to visit emitters directly usually.

Example

const stream = new StateStream('example')

// More info about emitter, check document below please
stream.emitter('emitterA', () => state => state)

// You can get emitterA through instance or instance.emitters
console.log(stream.emitterA === stream.emitters.emitterA)
// true

next

next: (updater: Function) => void

next is an operator using for updating state. It receive one parameter:

  • updater: A function define how to update state. Receive current state and return next state.

Example

const stream = new StateStream('example', 0)

stream.subscribe(state => console.log(state))

stream.next(prevState => prevState + 2)
stream.next(() => 10)
stream.next(prevState => prevState - 3)

// console.log output:
// 0
// 2
// 10
// 7

emitter

emitter: (name: string, highOrderUpdater: Function) => void

emitter is an operator for create state updation operator. It receive two parameter:

  • name:operator name
  • highOrderUpdater: high order updater, define function signature for operator and state updater.

Example

const stream = new StateStream('example', 0)

stream.emitter('emitterA', value => prevState => (prevState + value))
// it equals to:
// stream.emitterA = value => stream.next(prevState => (prevState + value))
// stream.emitters.emitterA = stream.emitterA

stream.state$.subscribe(state => console.log(state))

// you can call emitterA as an operator on instance
stream.emitterA(1)
stream.emitterA(2)

// console.log output:
// 0
// 1
// 3

Using emitter to define state updater is a better way than calling next directly, because it helps you classify operators, and it is helpful when you using plugins like rxact-debugger.

getState

getState: () => currentState: any

getState will return current state of stream.

Example

const stream = new StateStream('example', 0)

stream.subscribe(state => {
  console.log(stream.getState(), state)
})

stream.next(() => 1)
stream.next(() => 2)

// console.log output:
// 0, 0
// 1, 1
// 2, 2

eventRunner

eventRunner: (streamFactory: Function, source?: any) => Observable

eventRunner is a function for running event stream. it receives two parameters:

  • streamFactory: A function accepting observable source and return new observable object.
  • source: the source value of the event stream. It can be any value, eventRunner will turn it to observable if it no observable. If it is undefined, eventRunner will use state as source value.

  • return an observable subscribing to event stream.

The observable object returned by streamFactory will subscribed automatically, it means eventRunner will run your stream immediately. And there is a new observable object subscribe the event stream returned by eventRunner. So you can do something else after event run.

Example

const stream = new StateStream('example', 5)

const factory = value$ => value$
  .delay(1000)
  .do((value) => stream.next((prevState) => value + prevState))

// no source passed,using state as source default
stream.plusStateAsync = () => eventRunner(factory)

// passing a value as source
stream.plusValueAsync = value => eventRunner(factory, value)

// passing an observable as source
stream.plusObservableAsync = value => eventRunner(factory, Observable.of(value))

stream.subscribe(state => console.log(state))

stream.plusStateAsync()
stream.plugsValueAsync(1)
stream.plusObservableAsync(2)

// console.log output:
// 5      - initial value
// 10     - plusStateAsync()
// 11     - plusValueAsync(1)
// 13     - plusObservableAsync(13)

stream.plusOne = () => stream.next(state => (state + 1))

const plusStateAsync$ = stream.plusStateAsync()

// you can chain events after eventRunner executed
plusStateAsync$
  .delay(1000)
  .do(() => stream.plusOne())
  .subscribe()

// console.log output:
// 26    - plusStateAsync()
// delay 1 s
// 27    - plusOne()

dispose

dispose is a function to unsubscribe StateStream.

Example

const stream = new StateStream('example', 0)

stream.subscribe(state => console.log(state))

stream.next(state => state + 1)

// unsubscribe
stream.dispose()

stream.next(state => state + 1)

// console.log output:
// 0
// 1
// no output after disposed

stream.getState()
// 1
// 卸载后依然可以拿到当前值,并且可以看到卸载后的 state 更新操作没有生效。
// you can still get state after disposed, but state updation after disposed will not work.

results matching ""

    No results matching ""