Redux saga异步管理与生成器详解
作者:碰磕 发布时间:2023-07-24 02:53:52
redux-saga
在学习它之前先了解es6生成器
生成器
关键字:yield
next()
定义函数需要在函数名前急+*
号
function *test(){
console.log("11111",'第一次无效无值')
let input1=yield "111-输出";
console.log("2222",input1)
let input2=yield "2-输出";
console.log("1111213",input2)
let input3=yield "3-输出";
console.log("1111213",input3)
}
通过yield
进行拦截
然后定义变量接收这个函数
var pengke_test=test()
再通过next()
进行执行
可传参,函数通过接收变量接收yield
的值就是传来的值
let res1=pengke_test.next('aaa')//执行一次就往yield下执行一段(第一次传值是无效的)
console.log(res1);
上方这是执行了第一次
再继续往下执行,直到没有了打印的done
会为true
用变量接收next()
最后得到的一个对象value(yelid传来的值)–与—done(是否不能继续执行)
let res2=pengke_test.next('bbb')//通过变量接收yield的值即传的bbb值
console.log(res2);
let res3=pengke_test.next('cccc')
console.log(res3);
let res4=pengke_test.next()
console.log(res4);//当没有yield了就打印done为true,value=undefined
上方就是生成器的基本使用了
封装可执行生成器
正常情况下肯定是通过封装函数实现调用请求
function getData1(){
return new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('data1')
}, 1000);
})
}
function getData2(){
return new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('data2')
}, 1000);
})
}
function getData3(){
return new Promise((resolve,reject)=>{
setTimeout(() => {
resolve('data3')
}, 1000);
})
}
function *gen(){
let f1=yield getData1();
console.log(f1);
let f2=yield getData2(f1);
console.log(f2);
let f3=yield getData3(f2);
console.log(f3);
}
function run(fn){
let g=fn()
function next(data){
let result=g.next(data);
if(result.done){
return result.value
}
result.value.then(res=>{
next(res)
})
}
next()
}
run(gen)
这样就学会了完结~
redux-saga这里用于异步管理
安装
npm i redux-saga
基本使用
目录结构
写法一
首页创建一个按钮进行触发
App.js
import React, { Component } from 'react';
import store from './redux/store';
class App extends Component {
render() {
return (
<div>
<button onClick={()=>{
if(store.getState().list1.length===0){
//dispatch
store.dispatch({
type:"get-list"
})
}else{
console.log("缓存",store.getState().list1)
}
}}>click-ajax-异步缓存</button>
</div>
);
}
}
export default App;
随后reducer.js中编写list1
这里判断传来的值如果type=change-list
就进行赋值
function reducer(prevState={
list1:[]
},action={}){
var newState={...prevState}
switch(action.type){
case "change-list":
newState.list1=action.payload;
console.log("newState=",newState)
return newState;
default:
return prevState;
}
}
export default reducer
导出给store.js
引用
store.js状态编写
这里使用redux-saga中的createSagaMiddleWare
然后运行了任务(watchSaga)
import {createStore,applyMiddleware} from 'redux'
import reducer from './reducer'
import createSagaMiddleWare from 'redux-saga'
import watchSaga from './saga';
const SagaMiddleWare=createSagaMiddleWare();//生成
const store= createStore(reducer,applyMiddleware(SagaMiddleWare))//应用
SagaMiddleWare.run(watchSaga)//saga任务,
export default store
然后开始创建任务在saga.js中
take:监听组件发来的action
fork:同步执行异步处理函数
put:发出新的action
call:发出异步请求
/**
* saga任务
*/
import {take,fork,put,call} from 'redux-saga/effects'
function *watchSaga(){
while(true){
//take 监听 组件发来的action
yield take("get-list")
//fork 同步执行异步处理函数
yield fork(getList)
}
}
function *getList(){
//这里做异步处理的
//call函数发异步请求
let res= yield call(getListAction)//参数是返回值为promise对象的函数
//等待call执行完才会执行
yield put({
type:'change-list',
payload:res
})
//put函数发出新的action
}
function getListAction(){
return new Promise((resolve,reject)=>{
setTimeout(() => {
resolve(["123132","碰磕"])
}, 2000);
})
}
export default watchSaga
然后导出给store
进行使用
这样一个流程就这样走完了,从而实现第一次点击页面数据会执行该任务并且给list1赋值,第二次点击就可以直接拿到值了.over~
写法二
将take与fork进行替换
只需要用到takeEvery
//原来:
function *watchSaga2(){
while(true){
//take 监听 组件发来的action
yield take("get-list2")
//fork 同步执行异步处理函数
yield fork(getList2)
}
}
//现在:
function *watchSaga2(){
//写法2
yield takeEvery("get-list2",getList2)
}
使用多个saga
使用到redux-saga/effects
中的all
import {all} from 'redux-saga/effects'
import watchSaga1 from './saga/saga1';
import watchSaga2 from './saga/saga2';
function *watchSaga(){
yield all([watchSaga1(),watchSaga2()])
}
export default watchSaga;
将两个saga引入到该文件最终并且使用all进行执行~
来源:https://blog.csdn.net/m_xiaozhilei/article/details/125654217
猜你喜欢
- 前段时间在生活中偶尔需要对某些文件进行重命名,而且是随机名字,刚开始是手动重命名然后在键盘上胡乱打一些字母数字,时间长了发现也挺麻烦的,于是
- 目录概述索引数据结构二叉树红黑树B-TreeB+TreeHash索引InnoDB 索引实现(聚集)索引文件和数据文件是分离的(非聚集)聚集索
- 投资有风险,选择需谨慎。 股票交易数据分析可直观股市走向,对于如何把握股票行情,快速解读股票交易数据有不可替代的作用!1 数据预处
- 本文实例为大家分享了Python函数实现学员管理系统的具体代码,供大家参考,具体内容如下这个是一个简单的管理程序输入姓名,年龄,性别(也可以
- 函数input()的工作原理函数input()让程序暂停运行,等待用户输入一些文本。获取用户输入后,Python将其存储在一个变量中,以方便
- 本文来给大家介绍一个php版淘宝网查询商品接口代码的例子,下面要改成你的信息的在代码后面都有说明了,同时sdk包我们也要官方下载。下载SDK
- 一、python批量解压提示:如果是重要数据解压前请先备份,解压后会覆盖原压缩文件!!解压前:解压后:文件名为英文:文件名中包含中文:代码如
- 本文实例讲述了wxPython主框架的简单用法,分享给大家供大家参考。具体如下:程序代码如下:import wx class MyApp(w
- 初步认识k-means翻译过来就是K均值聚类算法,其目的是将样本分割为k个簇,而这个k则是KMeans中最重要的参数:n_clusters,
- 关于模型保存的一点心得saver = tf.train.Saver(max_to_keep=3)在定义 saver 的时候一般会定义最多保存
- 什么是计算属性???1、在computed中,可以定义一些属性,这些属性叫做【计算属性】2、计算属性的本质是一个方法,不过一般是将他们的名称
- <script> Array.prototype.swap = function(i, j) { var temp = this
- Internet Explorer 8 Beta 测试了一年多之后,今天,IE8 终于发布了。它绝对好过 IE7,还有一些不错的新功能,如
- 1、需要模块以及测试工具模块名:pyserial使用命令下载:python -m pip install pyserial串口调试工具:ss
- 定时任务:1、 线程睡眠函数 sleep() ——粗暴!一直占有 CPU 资源,导致后续操作无法执行2、 threading.Timer(1
- 为什么要实现分页?在大部分网站中分页的功能都是必要的,尤其是在后台管理中分页更是不可或缺分页能带给用户更好的体验,也能减轻服务器的压力对于分
- 1. 概述若要将数据库移动或更改到同一计算机的不同 SQL Server 实例,分离和附加数据库会很有用;用户可以分离数据库的数据和事务日志
- Ajax,全称为Asynchronous JavaScript and XML,即异步的JavaScript和XML。它不是一门编程语言,而
- 如下所示:def translationCipher(msg,key): result = ["&quo
- 最近项目中遇见 Jquery Ajax 缓存问题,load出来的页面状态有时正常,有时不对,记录一下,希望对大家有帮助使用jquery里lo