网络编程
位置:首页>> 网络编程>> JavaScript>> Redux saga异步管理与生成器详解

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

作者:碰磕  发布时间:2023-07-24 02:53:52 

标签:Redux,saga,异步管理,生成器

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

基本使用

目录结构

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

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com