Serivce
本节主要讲如何定义一个Service ?
简单的Service
interface State {
// 定义State的类型
}
class DemoService extends Service<State> {
defaultState: State = {
// 实现State
}
}
上面是一个Service最基本的代码,defaultState是整个service的初始数据,必须提供
Reducer
reducer 同redux里面的reducer,由当前的state通过一系列reducer逻辑返回一个全新的state:
interface State {
count: number
}
class DemoService extends Service<State>{
defaultState: State ={
count: 0
}
@Reducer()
add(state:State, x: number):State {
return { count: state.count + x }
}
@Reducer()
reset():State {
return this.defaultState
}
}
ImmerReducer
reducer比较占用内存,同时当state结构复杂之后进行reducer也是一件十分困难的事情,因此这里引入了一个immutable方案,作用与reducer一致,不过你可以在函数里面直接修改state:
interface State {
count: number
}
class DemoService extends Service<State>{
defaultState: State ={
count: 0
}
@Reducer()
add1(state:State, x: number):State {
return { count: state.count + x }
}
@ImmerReducer()
add2(state:State, x: number) {
state.count += x
}
}
add1和add2作用完全一致
Effect
Effect用于处理副作用
interface State {
count: number
}
const fetchRemoteCount = ({level: number}) => from(fetch(`https://xxxxx?level=${level}`))
class DemoService extends Service<State>{
defaultState: State ={
count: 0
}
@ImmerReducer()
setCount(state:State, x: number) {
state.count = x
}
@Effect()
getRemoteCount(level$: Observable<number>, state$: Observable<State>): Observable<EffectAction> {
return level$.pipe(
switchMap(level => fetchRemoteCount({level})),
map(count => this.actions().setCount(count))
)
}
}
// 调用
const demoService = // 获取DemoService实例
const actions = demoService.getActionMethods()
actions.getRemoteCount(1)
actions.getRemoteCount(2)
//...
以上就是一个简单的请求api的例子, 下边actions
每一次调用getRemoteCount(x)
的时候,level$
流都会推出一个x,然后通过switchMap操作符,这个符号就会对之前fetchRemoteCount
产生的流进行unsubscribe(对应具体的rx请求库就会自动cancel正在进行的请求)并再次调用fetchRemoteCount({level})
产生一个 新流,并马上切换到这个新流上。
然后,使用map
操作符将请求获取的结果count
转化为EffectAction
不要在effect方法里面直接调用this.getState, this.getState$, 请直接使用第二个传入参数state$
不要在effect方法里面直接调用某个action,你应当使用this.actions()然后返回Observable<EffectAction> (详见Notice #1)
effect中所有触发的action都是异步的
Notice #1: this.actions()
this.actions()函数的返回是一个actionCreator集合,调用这些actionCreator可以得到一个action描述对象(EffectAction),如:
this.actions().setCount(2) // 将会返回一个setCount的actionCreator:
{
service: demoService, // 当前action对应的service实例
actionName: 'setCount', // 触发action的名字
params: 2, // 触发action的调用参数
}
Last updated
Was this helpful?