saga分类react
take 等待一个动做发生,只发生一次redux
put 派发一个动做app
takeEvery 监听每一个动做异步
call 执行一个动做函数
index.js 导出createSagaMiddeware函数,这个函数执行完返回一个中间件ui
effectthis
综上所述咱们先有个rootSaga做为惟一入口spa
src/sagas.jscode
// import {takeEvery,put,all,call} from 'redux-saga/effects';
// import * as types from './store/action-types';
// const delay=ms => new Promise(function(resolve,reject){
// setTimeout(function(){
// resolve()
// },ms)
// })
// function* add(dispatch,action,all){
// // setTimeout(function(){
// // dispatch({type:types.ADD})
// // },1000)
// 帮我执行这个动做
// yield call(delay,5000)
// 帮我派发这个动做
// yield put({type:types.ADD})
// }
// function* logger(action){
// console.log(action);
// }
// function* watchLogger(){
// yield takeEvery('*',logger)
// }
// function* watchAdd(){
// yield takeEvery(types.ADD_ASYNC,add)
// }
// export function* rootSaga({getState,dispatch}){
// yield all([watchAdd(),watchLogger()]) ;
// }
// import {take,takeEvery,put,all,call} from 'redux-saga/effects';
import {takeEvery,take,put,call} from './redux-saga/effects';
import * as types from './store/action-types';
// export function* rootSaga(){
// // yield {type:'take',acionType:ADD_ASYNC}
// // while(true){
// let action=yield take(types.ADD_ASYNC);
// yield put({type: types.ADD});
// // }
// }
const delay=ms => new Promise(function(resolve,reject){
setTimeout(function(){
resolve()
},ms)
})
function* add(){
// setTimeout(function(){
// dispatch({type:types.ADD})
// },1000)
yield call(delay,1000)
yield put({type:types.ADD})
}
export function* rootSaga(){
let action=yield takeEvery(types.ADD_ASYNC,add);
}
复制代码
src/components/Counter.jscomponent
import React,{Component} from 'react'
import {connect} from 'react-redux';
import actions from '../store/actions';
class Counter extends Component{
render() {
return (
<div> <p>{this.props.number}</p> <button onClick={this.props.increment}>+</button> </div>
)
}
}
export default connect(
state => state,
actions
)(Counter);
复制代码
src/store/index.js
import {createStore, applyMiddleware} from 'redux';
import reducer from './reducer';
import createSagaMiddleware from 'redux-saga';
import {rootSaga} from '../saga';
let sagaMiddleware=createSagaMiddleware();//返回一个中间件
let store=applyMiddleware(sagaMiddleware)(createStore)(reducer);//应用中间件
sagaMiddleware.run(rootSaga,store);//执行Genrator函数
window.store=store;
export default store;
复制代码
src/store/actions.js
import * as types from './action-types';
export default {
increment() {
return {type:types.INCREMENT}
}
}
复制代码
action-types.js #
export const INCREMENT='INCREMENT';
复制代码
reducer.js
import * as types from './action-types';
export default function (state={number:0},action) {
switch(action.type){
case types.INCREMENT:
return {number: state.number+1};
default:
return state;
}
}
复制代码
** src/saga.js #**
import {takeEvery,put} from 'redux-saga/effects';
import * as types from './store/action-types';
const delay=ms => new Promise((resolve,reject) => {
setTimeout(() => {
resolve();
},ms);
});
export function* increment(dispatch) {
yield delay(1000);
yield put({type:types.INCREMENT});
}
export function* rootSaga({getState,dispatch}) {
//takeEvery接受每个将停派发给仓库的动做,每个INCREMENT_ASYNC动做,看成发生的时候,若是对应执行对应的监听生成器
yield takeEvery(types.INCREMENT_ASYNC,increment,dispatch);
}
复制代码
index.js
function createChannel() {
//对象每个动做对应一个回调函数
let takers={};
function subscribe(actionType,cb) {
takers[actionType]=cb;
}
function publish(action) {//{type:ADD}
//看看有没有人监听
let taker=takers[action.type]
if (taker) {//若是有执行监听函数而且删除监听函数
let tmp=taker;
delete taker[action.type];
tmp(action);
}
}
return {subscribe,publish};
}
let channel=createChannel();
function createSagaMiddelware() {
function sagaMiddelware({getState,dispatch}){
//负责把gernerator执行完毕 co库 rootSaga
function run(iterator){//(rootSaga,store)
//执行获得迭代器,next获得值,多是器也多是迭代器
let it = typeof iterator == 'function'?iterator():iterator;
function next(input){
let {value: effect,done}=it.next(input);
if(!done){//若是迭代器没有完成
//若是这个属性是个函数,他就是genrator
if(typeof effect[Symbol.iterator] == 'function'){
run(effect);
next();
}else{
}
switch(effect.type){
//等待一个动做发生,至关于注册一个监听
case 'take':
let {actionType}=effect;
channel.subscribe(actionType,next);
break;
case 'put':
let {action}=effect;
dispatch(action);
next(action);
break;
case 'fork':
let {worker}=effect;
run(worker);
next();
break;
case 'call':
let {fn,args}=effect;
fn(...args).then(next);
break;
default:
break;
}
}
}
next()
}
sagaMiddelware.run = run;
return function(next){
//下面的是真正的dispatch函数
return function(action){
channel.publish(action)
next(action)
}
}
}
return sagaMiddelware;
}
export default createSagaMiddelware;
复制代码
effect.js
//这里全部的函数都会返回一个effect,effect就是一个普通对象
//effect对象都有一个type属性
function take(actionType) {
return {
type: 'take',
actionType
}
}
function put(action) {
return {
type: 'put',
action
}
}
function fork(worker) {
return {
type: 'fork',
worker
}
}
function call(fn,...args) {
return {
type: 'call',
fn,
args
}
}
//监听每个动做类型,当此动做发生的时候执行对应的worker
//takeEvery它会单开一个任务,并不会阻塞当前saga
function* takeEvery(actionType,worker) {
yield fork(function* () {
while (true) {
let action=yield take(actionType);
yield worker(action);
}
})
}
//takerEvery的结果是一个迭代器
//iterator
export {
take,
put,
takeEvery,
call
}
复制代码