初识react(四) react中异步解决方案之 redux-saga

回顾

  • 初识react(一) 揭开jsx语法和虚拟DOM面纱
  • 初识react(二) 实现一个简版的html redux.js的demo
  • 初识react(三)在 react中使用redux来实现简版计数器
  • 初识react(四) react中异步解决方案之 redux-saga
  • 初识react(五) 数据流终极解决方案 dva(零配置)

今天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实现一个异步计数器

由于目录结构跟上篇文章一样,在这里就只把变动的部分单独抽离出来讲解

  • 先回顾下初识react(三)在 react中使用redux来实现简版计数器

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-sagaimport  rootSaga from "../saga" //引入我们上面写好的rootSagaimport reducer from "./reducers"let sagaMiddleware =createSagaMiddleware(); //执行得到saga中间件let store = createStore(reducer,applyMiddleware(sagaMiddleware)); //使用中间件sagaMiddleware.run(rootSaga); //开始执行rootSagaexport  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(<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函数

最后在梳理下整个过程

  • 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、页面刷新

  • 更多优质文章参考

  • redux所有源码解析戳这里

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367296.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# WinFrom 关于MDI

dev是一个牛B 到没边的控件 我们正常用winform做个原始mdi窗体 一点都不好看 但 用的dev只需要一个控件 就可让显示舒服多了 建一个项目 上边放一个 xtraTabbedMdiManager1 一个button1 button1.click如下&#xff1a; Form frm new Form(); frm.MdiParent this; frm.Text &…

Jfinal 文件上传

JFinal上传文件 uploadify 可以在http://www.uploadify.com/ 下载。 在原项目的基础上。 uploadify使用&#xff1a; <input id"file_upload_1" name"file_upload" type"file" multiple"true"> /** param uploader 文件上传方法…

轻量级的开源集成:Apache Camel还是Spring集成?

首先&#xff0c;为全面披露信息&#xff0c;在过去的1.5年中&#xff0c; 我一直担任 FuseSource&#xff08;现为Red Hat&#xff09; 的顾问&#xff0c;为零售&#xff0c;运输&#xff0c;银行/金融等不同行业的大型和小型公司提供SOA和集成项目支持。我的专长是使用该领域…

WePY:在质疑中前进 | 文末福利

WePY 作者介绍 Q: 先介绍一下自己吧~ Gcaufy: 我 2011 年大学毕业之后&#xff0c;阴错阳差的走上了 Web 开发的道路。15 年之前算是自由职业 SOHO 工作&#xff0c;主要给一些国外的大公司做外包系统&#xff0c;更多的是做后端开发。15 年之后以前端工程师的身份加入腾讯&a…

MySQL/MariaDB表表达式(3):视图

视图是表表达式的一种&#xff0c;所以它也是虚拟表。对视图操作的时候会通过语句动态的从表中临时获取数据。 1.创建、修改视图 CREATE [OR REPLACE][ALGORITHM {UNDEFINED | MERGE | TEMPTABLE}]VIEW [IF NOT EXISTS] view_name [(column_list)]AS select_statement[WITH [C…

Event Loop 其实也就这点事

前段时间在网上陆续看了很多关于 Event loop 的文章&#xff0c;看完也就混个眼熟&#xff0c;可能内心深处对这种偏原理的知识有一些抵触心情&#xff0c;看完后也都没有去深入理解。最近在看 Vue 的源码&#xff0c;在读到关于 nextTick 的实现时&#xff0c;总有一种似曾相识…

Kudu系列: Kudu主键选择策略

每个Kudu 表必须设置Pimary Key(unique), 另外Kudu表不能设置secondary index, 经过实际性能测试, 本文给出了选择Kudu主键的几个策略, 测试结果纠正了我之前的习惯认知. 简单介绍测试场景: 表中有一个unqiue字段Id, 另外还有一个日期维度字段histdate, 有三种设置kudu PK的方法…

OSS网页上传和断点续传(OSS配置篇)

OSS网页上传和断点续传主要根据BrowserJS-SDK和相关文档整理而得&#xff0c;快速构建OSS上传应用 一、Bucket设置 浏览器中直接访问OSS需要开通Bucket的CORS设置 将allowed origins设置成 *将allowed methods设置成 PUT, GET, POST, DELETE, HEAD将allowed headers设置成 *将e…

小程序各种姿势实现登录

喜闻乐见的背景时间--由于最近接触小程序比较多&#xff0c;又刚好经历过小程序的自动登录时代以及现在的点击登录时代。结合自己的实践以及观察到其他小程序的做法&#xff0c;就有了这篇小分享~ 本文可能涉及的内容-- 更新 首先感谢shaonialife同学的精彩评论~ 可能由于用词…

BBS-登录

from django.db import models# Create your models here. from django.contrib.auth.models import AbstractUser#用户 class UserInfo(AbstractUser):nidmodels.AutoField(primary_keyTrue)telephonemodels.CharField(max_length32)avatarmodels.FileField(upload_toavatar/,…

使用Mockito和BeanPostProcessors在Spring注入测试双打

我非常确定&#xff0c;如果您曾经使用过Spring并且熟悉单元测试&#xff0c;那么您会遇到与您不想修改的Spring应用程序上下文中注入模拟/间谍&#xff08;测试双打&#xff09;有关的问题。 本文介绍了一种使用Spring组件解决此问题的方法。 项目结构 让我们从项目结构开始&…

二叉搜索时与双向链表python_JZ26-二叉搜索树与双向链表

1、中序遍历&#xff0c;当前结点&#xff0c;以及左侧排好序的双向链表&#xff0c;再调整当前结点的指针指向最前结点/* struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x) :val(x), left(NULL), right(NULL) {} };*/ class Solution …

html右缩进怎么设置,WPS中怎么设置右缩进两个字符?

回答&#xff1a;打开我们的Word文档&#xff0c;调整好我们的文字内容&#xff0c;然后全选我们的文字内容&#xff0c;注意要分段时按下键盘上的回车键另起一行。请点击输入图片描述接着&#xff0c;我们点击顶部菜单栏的“开始”菜单&#xff0c;在开始菜单下面的子菜单中找…

VS2013专业版+QT5.6.3+qt-vs-addin-1.2.5环境搭建

一、工具资料&#xff1a; 1.vs2013专业版地址&#xff1a;http://download.csdn.net/download/u010368556/10238145 2.qt各版本地址&#xff1a;http://download.qt.io/archive/qt/ 3.qt-vs插件地址&#xff1a;http://download.qt.io/archive/vsaddin/ 二、环境搭建过程&…

使用ActiveMQ和HornetQ通过WebSocket通过STOMP轻松进行消息传递

消息传递是用于构建不同级别的分布式软件系统的极其强大的工具。 通常&#xff0c;至少在Java生态系统中&#xff0c;客户端&#xff08;前端&#xff09;从不直接与消息代理&#xff08;或交换&#xff09;进行交互&#xff0c;而是通过调用服务器端&#xff08;后端&#xff…

【laravel】【转发】laravel 导入导出excel文档

1、简介 Laravel Excel 在 Laravel 5 中集成 PHPOffice 套件中的 PHPExcel &#xff0c;从而方便我们以优雅的、富有表现力的代码实现Excel/CSV文件的导入和 导出 。 该项目的GitHub地址是&#xff1a; https://github.com/Maatwebsite/Laravel-Excel 。 本文我们将在Laravel中…

你真的了解css像素嘛?

在日常开发中&#xff0c;px一定是大家接触过最多的css单位&#xff0c;但是你真的了解px嘛&#xff1f;1px在屏幕中到底是多大呢&#xff1f;另外不知道大家有没有过下面这些疑惑: 为什么一个元素在pc上和移动端的物理尺寸不一样&#xff0c;但是两者的视觉效果上却差不多呢&…

mysql for mac中文_mysql for Mac 下创建数据表中文显示为?的解决方法

在我的绝版Mac mini下安装了mysql 5.7版本&#xff0c;实例中&#xff0c;在通过load data 导入数据时发现表中的中文显示为 &#xff1f;通过百度&#xff0c;发现多个版本的解决方法&#xff0c;将其中一个成功解决的方法贴上来&#xff1a;大多方法都是这样&#xff1a;需要…

计算机科学计算方面分为,计算机方面的专业分为哪些类?【资讯与计算科学】和【电脑科学与技术专业】有什么不同?...

计算机方面的专业分为哪些类&#xff1f;【资讯与计算科学】和【电脑科学与技术专业】有什么不同&#xff1f;以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;计算机方面的专业分为哪些类&am…

Java异常处理教程(包含示例和最佳实践)

异常是可能在程序执行期间发生的错误事件&#xff0c;它会破坏其正常流程。 Java提供了一种健壮且面向对象的方式来处理异常情况&#xff0c;称为Java异常处理 。 我们将在本教程中研究以下主题。 Java异常处理概述 异常处理关键字 异常层次 有用的异常方法 Java 7自动资源…