react实现异步插件_初识react(四) react中异步解决方案之 redux-saga
回顾
今天demo是实现一个异步的计算器,探究redux-saga工作流程
简介
redux-saga 是一个 redux 的中间件,而中间件的作用是为 redux 提供额外的功能。
由于在 reducers 中的所有操作都是同步的并且是纯粹的,即 reducer 都是纯函数,纯函数是指一个函数的返回结果只依赖于它的参数,并且在执行过程中不会对外部产生副作用,即给它传什么,就吐出什么。
但是在实际的应用开发中,我们希望做一些异步的(如Ajax请求)且不纯粹的操作(如改变外部的状态),这些在函数式编程范式中被称为“副作用”。
redux-saga 就是用来处理上述副作用(异步任务)的一个中间件。它是一个接收事件,并可能触发新事件的过程管理者,为你的应用管理复杂的流程。
redux-saga工作原理
对generator不了解的,看下阮一峰 generator讲解
sages 采用 Generator 函数来 yield Effects(包含指令的文本对象)。
Generator 函数的作用是可以暂停执行,再次执行的时候从上次暂停的地方继续执行
Effect 是一个简单的对象,该对象包含了一些给 middleware 解释执行的信息。
你可以通过使用 effects API 如 fork,call,take,put,cancel 等来创建 Effect。
redux-saga分类
worker saga 做左右的工作,如调用API,进行异步请求,获取异步封装结果
watcher saga 监听被dispatch的actions,当接受到action或者知道其被触发时,调用worker执行任务
root saga 立即启动saga的唯一入口
基本介绍已经讲完了,当做完一个demo后,回头再看redux-saga官网或者上面讲解,可能会有更深的体会
使用redux-saga实现一个异步计数器
由于目录结构跟上篇文章一样,在这里就只把变动的部分单独抽离出来讲解
1、修改actions/counter.js
增加一个异步记数的动作类型。
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;
复制代码
2、重点,在src目录下增加saga.js文件
//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分为三类 1、rootsaga 2、监听saga 3、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。在这段代码中将会体现,代码我们从上往下看。
2.1 saga工作流程(代码从下往上看)
默认导出了rootSaga,即saga的入口文件
watcher saga ->wactchAdd 负责监听派发的动作,如果动作类型匹配,执行对应的 worker saga
上面的worker saga指代的是 add函数
2.2 redux-saga/effects 副作用
在实际的应用开发中,我们希望做一些异步的(如Ajax请求)且不纯粹的操作(如改变外部的状态),这些在函数式编程范式中被称为“副作用”。
takeEvery=>负责监听,监听派发给仓库的动作,如果动作类型匹配的话,会执行对应的监听生成器->add
put=>派发动作,可以理解为dispatch
call=>告诉saga,执行delay函数,并把参数传过去。注意: delay函数必须返回promise
讲到这里,流程就说完了,接下来在store中执行rootSaga
3、在store/index引入rootSaga
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源码解析,底部会留下所有总结的代码仓库。
4、在counter.js组件中派发这个异步动作
代码跟上篇文章一模一样,只是增加了按钮实现异步操作
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(
{this.props.number}
{this.props.add(5)}}>+
{this.props.minus(1)}}>-
//增加异步操作
{this.props.async()}}>异步加10
)
}
}
export default connect(state=>({
...state
}),actions)(Counter)
复制代码终结,看效果。可以看出,点击后等待1s才加10。那我们就可以在call()中传入执行的异步函数(如ajax)来获取数据啦。我们这个例对应的delay函数
最后在梳理下整个过程
1、组件中调用了this.props.async(),返回的action对象=>{type:Types.ADD_ASYNC}会在connect方法中被派发
2、saga中takeEvery(Types.ADD_ASYNC,add),监听到动作的类型后,触发 worker saga =>add
3、worker saga中先 yield call(delay,1000); 执行delay方法,延时1s
4、yield put({type:Types.INCREMENT,count:10}); 最后派发的还是INCREMENT的类型
5、接着被reducer处理,更新state
6、页面刷新
react实现异步插件_初识react(四) react中异步解决方案之 redux-saga相关推荐
- react 组件封装原则_我理解的React:React 到底是什么?
希望本文能帮助没接触过 React 的同学,对React有个大致的理解. 最近要做一个"前端零基础的入门课程分享",很多非前端同学可能只是知道 React 是个前端框架,整体对 R ...
- fs react 使用 保存文件_入门TypeScript编写React
使用 create-react-app 开启 TypeScript Create React App 是一个官方支持的创建 React 单页应用程序的CLI,它提供了一个零配置的现代构建设置.当你使用 ...
- java 多线程 异步日志_精彩技巧(1)-- 异步打印日志的一点事
一.前言 最近刚刚结束转岗以来的第一次双11压测,收获颇多,难言言表, 本文就先谈谈异步日志吧,在高并发高流量响应延迟要求比较小的系统中同步打日志已经满足不了需求了,同步打日志会阻塞调用打日志的线程, ...
- 执行计划有时不准确_生产计划四个层次和解决方案
生产计划四个层次和解决方案 如何让ERP排出来的生产计划切实可用.让ERP生产计划模块不再成为ERP系统的瓶颈,这是很多实施顾问都想攻克的一个难题.那为什么这个生产计划就会这么难呢,这有多个因素的原因 ...
- python execute异步执行_封装了一个对mysql进行异步IO的小工具
作者(微信公众号):猿人学Python SanicDB 是为 Python的异步 Web 框架 Sanic 方便操作MySQL而开发的工具,是对 aiomysql.Pool 的轻量级封装.Sanic ...
- html中异步上传文件实现示例,HTML_html中异步上传文件实现示例,复制代码代码如下: form actio - phpStudy...
html中异步上传文件实现示例 复制代码代码如下: 复制代码代码如下: 这是html中最常见最简单的表单提交方式,但是这种方式必须会切换页面,也许有些时候我们希望可以在同一个页面与服务器进行交互,并不 ...
- react文字滚动插件_【赠书】Preact(React)核心原理详解
豆皮粉儿们,又见面了,今天这一期,由字节跳动数据平台的"winge(宝丁)",带大家见识见识前端"轮子"之一Preact框架. 提到Preact,你肯定会先想到 ...
- react打包后图片丢失_React系列四 - React脚手架
一. 认识脚手架 1.1. 前端工程的复杂化 如果我们只是开发几个小的demo程序,那么永远不需要考虑一些复杂的问题: 比如目录结构如何组织划分: 比如如何管理文件之间的相互依赖: 比如如何管理第三方 ...
- react 手指移开_代码简介:React的五个死亡手指
react 手指移开 Here are three stories we published this week that are worth your time: 这是我们本周发布的三个值得您关注的 ...
- react创建动态表格_教程:使用React创建电子表格
react创建动态表格 Related content 相关内容 First steps 第一步 Build a simple spreadsheet 建立一个简单的电子表格 Introducing ...
最新文章
- ASP.NET用户登录模块代码
- TP5 实现转盘抽奖
- FPGA篇(六)关于Modelsim仿真时不能编译`include文件解决办法【Verilog】【Modelsim】(转)
- 中粮集团对话农民丰收节交易会-万祥军:订单农业丰收经
- rsync实现文件同步
- MOS管的主要参数与重要特性
- 【渝粤题库】陕西师范大学164111 Java及JSP动态网页编程与应用 作业 (高起专)
- C#-ToString格式化
- 基于SSM + Redis的Shiro权限管理项目
- 网络通信第一课 C++封装HTTP请求报文说明
- matplotlib绘制李萨如图(二) animation实现动态2D李萨如图
- python 公众号文章发布_Python获取公众号文章
- 谷歌浏览器获取网页元素的xpath
- 计算机管理没有Android手机项,电脑没有手机驱动各品牌解决办法
- 非极大值抑制算法(NMS)
- 湘潭大学c语言作业系统学生端,作业收发系统学生端使用说明
- spss入门——简单的数据预处理到时间序列分析系列(四)
- Word - Word 文档如何切换简体字和繁体字?
- 「实在RPA·人社数字员工」促进人力社保数字办公战略转型
- web项目设置最小宽度
热门文章
- OpenStack实验:创建虚拟机的问题
- 从零开始的linux 第十九章(mv命令详解)
- linux中查找grep与find命令的使用
- 【Linux系统】部分基础命令手册
- React 详解,组件,条件渲染
- 微信小程序背景音乐的调试
- 移动应用图标生成工具,一键生成所有尺寸的应用图标
- python3 主函数_Python3---常见函数---if __name__ == __main__
- YAF 菜鸟的学习笔记
- java程序拦截dde漏洞问题_Office DDE漏洞学习笔记