Last active
May 2, 2017 11:16
-
-
Save xufei/bae6b1ef61403b60d9f2419b19f02815 to your computer and use it in GitHub Desktop.
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
const delay = (time) => { | |
return new Promise(resolve => setTimeout(resolve, time)); | |
}; | |
const serviceFactory = (timeout) => { | |
return async () => { | |
await delay(timeout); | |
return timeout; | |
}; | |
}; | |
class Simple extends Model { | |
constructor(config = { | |
name: 'simple', | |
state: { | |
foo: 0, | |
bar: 0, | |
counter: 0, | |
async: 0, | |
multiSteps: 0, | |
parallel: [0, 0], | |
race: 0, | |
}, | |
}) { | |
super(config); | |
} | |
/** | |
* 使用put操作修改state | |
* @param Action 一个Action实例 | |
*/ | |
foo({ payload: foo }) { | |
this.put({ | |
type: 'foo', | |
payload: { foo }, | |
}); | |
return foo; | |
} | |
/** | |
* 使用merge简化修改state | |
* @param Action 一个Action实例 | |
*/ | |
bar({ payload: bar }) { | |
this.merge({ | |
bar, | |
}); | |
} | |
/** | |
* 使用select操作选取state中的部分数据 | |
* @param Action 一个Action实例 | |
*/ | |
async add({ payload: inc }) { | |
const { counter } = this.state; | |
this.put({ | |
type: 'counter', | |
payload: { | |
counter: counter + inc, | |
}, | |
}); | |
} | |
/** | |
* 异步的action,在操作之后设置数据 | |
*/ | |
async asyncDemo(action) { | |
await delay(3000); | |
this.put(action); | |
return 'async demo'; | |
} | |
/** | |
* 在dispatch之后调用一些操作,dispatch默认也是返回promise的 | |
*/ | |
async asyncDispatchDemo(action) { | |
const result = await this.foo(action); | |
this.put({ | |
type: 'asyncDispatch', | |
payload: { | |
async: result, | |
}, | |
}); | |
return result; | |
} | |
/** | |
* 测试组合几个步骤 | |
*/ | |
async multiSteps({ payload: num }) { | |
const a = await this.add2(num); | |
const b = await this.add3(a); | |
return b; | |
} | |
// 普通方法,不需要被外部dispatch调用,所以参数不必一定是action | |
async add2(num) { | |
await delay(3000); | |
const result = num + 1; | |
this.put({ | |
type: 'add2', | |
payload: { | |
multiSteps: result, | |
}, | |
}); | |
return result; | |
} | |
// 普通方法,不需要被外部dispatch调用,所以参数不必一定是action | |
async add3(num) { | |
await delay(3000); | |
const result = num + 3; | |
this.put({ | |
type: 'add3', | |
payload: { | |
multiSteps: result, | |
}, | |
}); | |
return result; | |
} | |
/** | |
* 并行的action,等所有事情做完之后发action | |
*/ | |
async parallelDemo() { | |
const service1 = serviceFactory(3000); | |
const service2 = serviceFactory(2000); | |
const [a, b] = await Promise.all([ | |
service1(), | |
service2(), | |
]); | |
this.put({ | |
type: 'parallel', | |
payload: { | |
parallel: [a, b], | |
}, | |
}); | |
return [a, b]; | |
} | |
/** | |
* 竞争的action,其中一个做完之后就发action | |
*/ | |
async raceDemo() { | |
const service = serviceFactory(2000); | |
const result = await Promise.race([ | |
service(), | |
delay(3000), | |
]); | |
const race = result || 'race'; | |
this.put({ | |
type: 'race', | |
payload: { | |
race, | |
}, | |
}); | |
return result; | |
} | |
} | |
export { Simple }; |
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
import React from 'react'; | |
import { connect } from 'react-redux'; | |
const Simple = ({ simple, dispatch }) => { | |
const style = { | |
border: '1px solid red', | |
display: simple.loading ? '' : 'none', | |
}; | |
const foo = () => { | |
dispatch({ type: 'simple/foo', payload: 233 }); | |
}; | |
const bar = () => { | |
dispatch({ type: 'simple/bar', payload: 666 }); | |
}; | |
const add = () => { | |
dispatch({ type: 'simple/add', payload: 12306 }); | |
}; | |
const asyncDemo = () => { | |
dispatch({ type: 'simple/asyncDemo', payload: { async: 666 } }) | |
.then((a) => { console.log(a); }); | |
}; | |
const parallelDemo = () => { | |
dispatch({ type: 'simple/parallelDemo' }) | |
.then((a) => { console.log(a); }); | |
}; | |
const raceDemo = () => { | |
dispatch({ type: 'simple/raceDemo' }) | |
.then((a) => { console.log(a); }); | |
}; | |
const multiStepDemo = () => { | |
dispatch({ type: 'simple/multiSteps', payload: 1 }) | |
.then((a) => { console.log(a); }); | |
}; | |
return ( | |
<div> | |
<button onClick={foo} >foo</button> | |
<button onClick={bar} >bar</button> | |
<button onClick={add} >add counter</button> | |
<button onClick={asyncDemo} >async</button> | |
<button onClick={multiStepDemo} >multi step</button> | |
<button onClick={parallelDemo} >parallel</button> | |
<button onClick={raceDemo} >race</button> | |
<h2>foo: { simple.foo }</h2> | |
<h2>bar: { simple.bar }</h2> | |
<h2>counter: { simple.counter }</h2> | |
<h2>async: { simple.async }</h2> | |
<h2>multi step: { simple.multiSteps }</h2> | |
<h2>parallel: { simple.parallel }</h2> | |
<h2>race: { simple.race }</h2> | |
<h2 style={style}>loading</h2> | |
</div> | |
); | |
}; | |
Simple.propTypes = { | |
}; | |
const mapStateToProps = (state) => { | |
const { simple } = state; | |
return { | |
simple, | |
}; | |
}; | |
export default connect(mapStateToProps)(Simple); |
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
import { Simple } from './simple' | |
describe('simple model test', () => { | |
it('foo should work', () => { | |
const app = new App() | |
const simple = new Simple() | |
app.model('simple', simple) | |
const dispatch = app.dispatch | |
expect(simple.state.foo).toEqual(0) | |
dispatch({ type: 'simple/foo', payload: 1 }) | |
expect(simple.state.foo).toEqual(1) | |
}) | |
it('bar should work', () => { | |
const app = new App() | |
const simple = new Simple() | |
app.model('simple', simple) | |
const dispatch = app.dispatch | |
expect(simple.state.bar).toEqual(0) | |
dispatch({ type: 'simple/bar', payload: 1 }) | |
expect(simple.state.bar).toEqual(1) | |
}) | |
it('add should work', () => { | |
const app = new App() | |
const simple = new Simple() | |
app.model('simple', simple) | |
const dispatch = app.dispatch | |
expect(simple.state.counter).toEqual(0) | |
dispatch({ type: 'simple/add', payload: 1 }) | |
expect(simple.state.counter).toEqual(1) | |
}) | |
it('asyncDemoshould work', async () => { | |
const app = new App() | |
const simple = new Simple() | |
app.model('simple', simple) | |
const dispatch = app.dispatch | |
expect(simple.state.counter).toEqual(0) | |
const result = await dispatch({ type: 'simple/asyncDemo', payload: 1 }) | |
expect(result).toEqual('async demo') | |
}) | |
it('multiSteps should work', () => { | |
const app = new App() | |
const simple = new Simple() | |
app.model('simple', simple) | |
const dispatch = app.dispatch | |
expect(simple.state.multiSteps).toEqual(0) | |
dispatch({ type: 'simple/multiSteps', payload: 1 }) | |
.then(() => { | |
expect(simple.state.multiSteps).toEqual(6) | |
}) | |
}) | |
it('asyncDispatchDemo should work', async () => { | |
const app = new App() | |
const simple = new Simple() | |
app.model('simple', simple) | |
const dispatch = app.dispatch | |
expect(simple.state.async).toEqual(0) | |
const num = await dispatch({ type: 'simple/asyncDispatchDemo', payload: 1 }) | |
expect(simple.state.async).toEqual(num) | |
}) | |
it('parallelDemo should work', async () => { | |
const app = new App() | |
const simple = new Simple() | |
app.model('simple', simple) | |
const dispatch = app.dispatch | |
expect(simple.state.parallel).toEqual([0, 0]) | |
await dispatch({ type: 'simple/parallelDemo' }) | |
expect(simple.state.parallel).toEqual([3000, 2000]) | |
}) | |
it('raceDemo should work', async () => { | |
const app = new App() | |
const simple = new Simple() | |
app.model('simple', simple) | |
const dispatch = app.dispatch | |
expect(simple.state.race).toEqual(0) | |
await dispatch({ type: 'simple/raceDemo' }) | |
expect(simple.state.race).toEqual(2000) | |
}) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
dva简化版
反复纠结是否需要提供兼容dva的call这样的操作,这个地方改了好几次……
实现了这些东西的一个基础的应用,用create-react-app创建的,构建大小gzip之后50多k