最近在学习dva,但发现官方文档有点滞后,所以自己记录下笔记,如有笔误或者理解不当的地方,还请指正
dva是一个基于 redux 和 redux-saga 的数据流方案,其中effects是Action 处理器,处理异步动作,基于 Redux-saga 实现。Effect 指的是副作用。根据函数式编程,计算以外的操作都属于 Effect,典型的就是 I/O 操作、数据库读写
在本model中调用action是不用加namespace,如果加上甚至会抛出警告,跨model调用才要加上namespace区分
-
call
阻塞
用于调用异步逻辑,支持 promiseconst result = yield call(fetch, payload);
-
put
不阻塞
用于触发 action,一般来触发reducer改变stateyield put({ type: 'todos/add', payload: 'Learn Dva' });
-
put.resolve
阻塞
功能与put一样,区别是put.resolve是阻塞的,执行完才进行下一步 -
select
不阻塞
用于从 state 里获取数据const { args } = yield select(state => state[namespace]);
-
take
阻塞
可以监听action的开始和结束阶段,take会阻塞到监听的事件触发,才执行下一步it('take', done => { const app = create(); app.model({ namespace: 'count', state: 0, reducers: { add(state, { payload }) { return state + payload || 1; }, }, effects: { *addDelay({ payload }, { put, call }) { yield call(delay, payload.delay || 100); yield put({ type: 'add', payload: payload.amount }); }, *test(action, { put, select, take }) { yield put({ type: 'addDelay', payload: { amount: 2 } }); // @@start 是监听put操作的第一步,即payload与state还没合并,这时state为0 //yield take('addDelay/@@start'); //@@end 是监听put操作的最后一步,即将payload与state合并,返回新的state,这时state为2 yield take('addDelay/@@end'); const count = yield select(state => state.count); yield put({ type: 'addDelay', payload: { amount: count, delay: 0 } }); }, }, }); app.start(); app._store.dispatch({ type: 'count/test' }); setTimeout(() => { expect(app._store.getState().count).toEqual(4); done(); }, 300); });
可以监听action数组,满足一个即可
it('take with array of actions', () => { const app = create(); let takenCount = 0; app.model({ namespace: 'count', state: null, reducers: { addRequest() { return 1; }, addFailure() { return -1; }, addSuccess() { return 0; }, }, effects: { *add(action, { put }) { yield put(