目录
  • redux-saga
  • 生成器
    • 封装可执行生成器
  • 安装
    • 基本使用
      • 写法一
      • 写法二
    • 使用多个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进行执行~

      声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。