今天demo是实现一个异步的计算器,探究redux-saga工做流程html
redux-saga 就是用来处理上述反作用(异步任务)的一个中间件。它是一个接收事件,并可能触发新事件的过程管理者,为你的应用管理复杂的流程。react
基本介绍已经讲完了,当作完一个demo后,回头再看redux-saga官网或者上面讲解,可能会有更深的体会git
因为目录结构跟上篇文章同样,在这里就只把变更的部分单独抽离出来说解github
import * as Types from "../action-types";
let actions ={
add(num){
return{type:Types.INCREMENT,count:num}
},
minus(num){
return{type:Types.DECREMENT,count:num}
},
//增长了一个异步记数的类型,用于在counter.js中派发动做
async(num){
return {type:Types.ADD_ASYNC}
}
};
export default actions;
复制代码
//takeEvery=>负责监听 put=>派发动做 call=>告诉saga,执行delay,并传入1000做为参数
import {takeEvery,put,call} from "redux-saga/effects";
import * as Types from "./store/action-types";
const delay = ms=>new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve()
},ms)
})
//saga分为三类 一、rootsaga 二、监听saga 三、worker干活的saga
function* add() {
yield call(delay,1000);
//就是指挥saga中间件向仓库派发动做
yield put({type:Types.INCREMENT,count:10});
}
function* watchAdd() {
//监听派发给仓库的动做,若是动做类型匹配的话,会执行对应的监听生成器
yield takeEvery(Types.ADD_ASYNC,add)
}
export default function* rootSaga() {
yield watchAdd()
}
复制代码
还记得上面说的,rudux-saga分类,root saga ->watcher saga -> worker saga。在这段代码中将会体现,代码咱们从上往下看。ajax
在实际的应用开发中,咱们但愿作一些异步的(如Ajax请求)且不纯粹的操做(如改变外部的状态),这些在函数式编程范式中被称为“反作用”。编程
讲到这里,流程就说完了,接下来在store中执行rootSagaredux
import {createStore,applyMiddleware} from 'redux';
import createSagaMiddleware from "redux-saga"; //引入redux-saga
import rootSaga from "../saga" //引入咱们上面写好的rootSaga
import reducer from "./reducers"
let sagaMiddleware =createSagaMiddleware(); //执行获得saga中间件
let store = createStore(reducer,applyMiddleware(sagaMiddleware)); //使用中间件
sagaMiddleware.run(rootSaga); //开始执行rootSaga
export default store;
复制代码
对于redux中间件没有讲解,这部份内容涉及东西比较多,也不太好理解,写这个react系列目的是尽量简单的让全部人理解,想看全部的redux源码解析,底部会留下全部总结的代码仓库。promise
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {connect} from "react-redux";
import actions from "../store/actions/counter"
class Counter extends Component {
render() {
console.log(this.props);
return(
<div>
<h1>{this.props.number}</h1>
<button onClick={()=>{this.props.add(5)}}>+</button>
<button onClick={()=>{this.props.minus(1)}}>-</button>
//增长异步操做
<button onClick={()=>{this.props.async()}}>异步加10</button>
</div>
)
}
}
export default connect(state=>({
...state
}),actions)(Counter)
复制代码
终结,看效果。能够看出,点击后等待1s才加10。那咱们就能够在call()中传入执行的异步函数(如ajax)来获取数据啦。咱们这个例对应的delay函数bash
一、组件中调用了this.props.async(),返回的action对象=>{type:Types.ADD_ASYNC}会在connect方法中被派发app
二、saga中takeEvery(Types.ADD_ASYNC,add),监听到动做的类型后,触发 worker saga =>add
三、worker saga中先 yield call(delay,1000); 执行delay方法,延时1s
四、yield put({type:Types.INCREMENT,count:10}); 最后派发的仍是INCREMENT的类型
五、接着被reducer处理,更新state
六、页面刷新