Redux saga异步管理与生成器详解

 更新时间:2023年02月06日 09:23:00   作者:碰磕  
这篇文章主要介绍了Redux saga异步管理与生成器,工作中使用了redux-saga这个redux中间件,如果不明白内部原理使用起来会让人摸不着头脑,阅读源码后特意对其原理做下总结

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进行执行~

到此这篇关于Redux saga异步管理与生成器详解的文章就介绍到这了,更多相关Redux saga异步管理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React Suspense解决竞态条件详解

    React Suspense解决竞态条件详解

    这篇文章主要为大家介绍了React Suspense解决竞态条件详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • React Context原理深入理解源码示例分析

    React Context原理深入理解源码示例分析

    这篇文章主要为大家介绍了React Context原理深入理解源码示例分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • React 中的重新渲染类组件及函数组件

    React 中的重新渲染类组件及函数组件

    这篇文章主要为大家介绍了React 中的重新渲染类组件及函数组件使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • 使用VScode 插件debugger for chrome 调试react源码的方法

    使用VScode 插件debugger for chrome 调试react源码的方法

    这篇文章主要介绍了使用VScode 插件debugger for chrome 调试react源码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • React RenderProps模式运用过程浅析

    React RenderProps模式运用过程浅析

    render props是指一种在 React 组件之间使用一个值为函数的 prop 共享代码的技术。简单来说,给一个组件传入一个prop,这个props是一个函数,函数的作用是用来告诉这个组件需要渲染什么内容,那么这个prop就成为render prop
    2023-03-03
  • React css-in-js基础介绍与应用

    React css-in-js基础介绍与应用

    随着React、Vue等支持组件化的MVVM前端框架越来越流行,在js中直接编写css的技术方案也越来越被大家所接受。为什么前端开发者们更青睐于这些css-in-js的方案呢,下面带你了解它
    2022-09-09
  • React使用useImperativeHandle自定义暴露给父组件的示例详解

    React使用useImperativeHandle自定义暴露给父组件的示例详解

    useImperativeHandle 是 React 提供的一个自定义 Hook,用于在函数组件中显式地暴露给父组件特定实例的方法,本文将介绍 useImperativeHandle的基本用法、常见应用场景,需要的可以参考下
    2024-03-03
  • React如何利用相对于根目录进行引用组件详解

    React如何利用相对于根目录进行引用组件详解

    这篇文章主要给大家介绍了关于React如何使用相对于根目录进行引用组件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-10-10
  • React关于antd table中select的设值更新问题

    React关于antd table中select的设值更新问题

    这篇文章主要介绍了React关于antd table中select的设值更新问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • webpack手动配置React开发环境的步骤

    webpack手动配置React开发环境的步骤

    本篇文章主要介绍了webpack手动配置React开发环境的步骤,webpack手动配置一个独立的React开发环境, 开发环境完成后, 支持自动构建, 自动刷新, sass语法 等功能...感兴趣的小伙伴们可以参考一下
    2018-07-07

最新评论