Redux saga異步管理與生成器詳解
redux-saga
在學(xué)習(xí)它之前先了解es6生成器
生成器
關(guān)鍵字:yield next()
定義函數(shù)需要在函數(shù)名前急+*號(hào)
function *test(){
    console.log("11111",'第一次無(wú)效無(wú)值')
    let input1=yield "111-輸出";
    console.log("2222",input1)
    let input2=yield "2-輸出";
    console.log("1111213",input2)
    let input3=yield "3-輸出";
    console.log("1111213",input3)
}
通過(guò)yield進(jìn)行攔截
然后定義變量接收這個(gè)函數(shù)
var pengke_test=test()
再通過(guò)next()進(jìn)行執(zhí)行
可傳參,函數(shù)通過(guò)接收變量接收yield的值就是傳來(lái)的值
let res1=pengke_test.next('aaa')//執(zhí)行一次就往yield下執(zhí)行一段(第一次傳值是無(wú)效的)
console.log(res1);
上方這是執(zhí)行了第一次
再繼續(xù)往下執(zhí)行,直到?jīng)]有了打印的done會(huì)為true
用變量接收next() 最后得到的一個(gè)對(duì)象value(yelid傳來(lái)的值)–與—done(是否不能繼續(xù)執(zhí)行)
let res2=pengke_test.next('bbb')//通過(guò)變量接收yield的值即傳的bbb值
console.log(res2);
let res3=pengke_test.next('cccc')
console.log(res3);
let res4=pengke_test.next()
console.log(res4);//當(dāng)沒(méi)有yield了就打印done為true,value=undefined
上方就是生成器的基本使用了
封裝可執(zhí)行生成器
正常情況下肯定是通過(guò)封裝函數(shù)實(shí)現(xiàn)調(diào)用請(qǐng)求
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)
這樣就學(xué)會(huì)了完結(jié)~
redux-saga這里用于異步管理
安裝
npm i redux-saga
基本使用
目錄結(jié)構(gòu)

寫法一
首頁(yè)創(chuàng)建一個(gè)按鈕進(jìn)行觸發(fā)
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
這里判斷傳來(lái)的值如果type=change-list就進(jìn)行賦值
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
導(dǎo)出給store.js引用
store.js狀態(tài)編寫
這里使用redux-saga中的createSagaMiddleWare
然后運(yùn)行了任務(wù)(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))//應(yīng)用
SagaMiddleWare.run(watchSaga)//saga任務(wù),
export default store
然后開(kāi)始創(chuàng)建任務(wù)在saga.js中
- take:監(jiān)聽(tīng)組件發(fā)來(lái)的action
 - fork:同步執(zhí)行異步處理函數(shù)
 - put:發(fā)出新的action
 - call:發(fā)出異步請(qǐng)求
 
/**
 * saga任務(wù)
 */
import {take,fork,put,call} from 'redux-saga/effects'
function *watchSaga(){
    while(true){
        //take 監(jiān)聽(tīng) 組件發(fā)來(lái)的action
        yield take("get-list")
        //fork 同步執(zhí)行異步處理函數(shù)
        yield fork(getList)
    }
}
function *getList(){
    //這里做異步處理的
    //call函數(shù)發(fā)異步請(qǐng)求
    let res= yield call(getListAction)//參數(shù)是返回值為promise對(duì)象的函數(shù)
   //等待call執(zhí)行完才會(huì)執(zhí)行
    yield put({
        type:'change-list',
        payload:res
    })
    //put函數(shù)發(fā)出新的action
}
function getListAction(){
    return new Promise((resolve,reject)=>{
        setTimeout(() => {
            resolve(["123132","碰磕"])
        }, 2000);
    })
}
export default watchSaga
然后導(dǎo)出給store進(jìn)行使用
這樣一個(gè)流程就這樣走完了,從而實(shí)現(xiàn)第一次點(diǎn)擊頁(yè)面數(shù)據(jù)會(huì)執(zhí)行該任務(wù)并且給list1賦值,第二次點(diǎn)擊就可以直接拿到值了.over~
寫法二
將take與fork進(jìn)行替換
只需要用到takeEvery
//原來(lái):
 function *watchSaga2(){
      while(true){
         //take 監(jiān)聽(tīng) 組件發(fā)來(lái)的action
          yield take("get-list2")
          //fork 同步執(zhí)行異步處理函數(shù)
          yield fork(getList2)
      }
 }
//現(xiàn)在:
 function *watchSaga2(){
    //寫法2
    yield takeEvery("get-list2",getList2)
 }
使用多個(gè)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;
將兩個(gè)saga引入到該文件最終并且使用all進(jìn)行執(zhí)行~
到此這篇關(guān)于Redux saga異步管理與生成器詳解的文章就介紹到這了,更多相關(guān)Redux saga異步管理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
 React?Suspense解決競(jìng)態(tài)條件詳解
這篇文章主要為大家介紹了React?Suspense解決競(jìng)態(tài)條件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
 使用VScode 插件debugger for chrome 調(diào)試react源碼的方法
這篇文章主要介紹了使用VScode 插件debugger for chrome 調(diào)試react源碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
 React RenderProps模式運(yùn)用過(guò)程淺析
render props是指一種在 React 組件之間使用一個(gè)值為函數(shù)的 prop 共享代碼的技術(shù)。簡(jiǎn)單來(lái)說(shuō),給一個(gè)組件傳入一個(gè)prop,這個(gè)props是一個(gè)函數(shù),函數(shù)的作用是用來(lái)告訴這個(gè)組件需要渲染什么內(nèi)容,那么這個(gè)prop就成為render prop2023-03-03
 React css-in-js基礎(chǔ)介紹與應(yīng)用
隨著React、Vue等支持組件化的MVVM前端框架越來(lái)越流行,在js中直接編寫css的技術(shù)方案也越來(lái)越被大家所接受。為什么前端開(kāi)發(fā)者們更青睞于這些css-in-js的方案呢,下面帶你了解它2022-09-09
 React使用useImperativeHandle自定義暴露給父組件的示例詳解
useImperativeHandle?是?React?提供的一個(gè)自定義?Hook,用于在函數(shù)組件中顯式地暴露給父組件特定實(shí)例的方法,本文將介紹?useImperativeHandle的基本用法、常見(jiàn)應(yīng)用場(chǎng)景,需要的可以參考下2024-03-03
 React如何利用相對(duì)于根目錄進(jìn)行引用組件詳解
這篇文章主要給大家介紹了關(guān)于React如何使用相對(duì)于根目錄進(jìn)行引用組件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10
 React關(guān)于antd table中select的設(shè)值更新問(wèn)題
這篇文章主要介紹了React關(guān)于antd table中select的設(shè)值更新問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
 webpack手動(dòng)配置React開(kāi)發(fā)環(huán)境的步驟
本篇文章主要介紹了webpack手動(dòng)配置React開(kāi)發(fā)環(huán)境的步驟,webpack手動(dòng)配置一個(gè)獨(dú)立的React開(kāi)發(fā)環(huán)境, 開(kāi)發(fā)環(huán)境完成后, 支持自動(dòng)構(gòu)建, 自動(dòng)刷新, sass語(yǔ)法 等功能...感興趣的小伙伴們可以參考一下2018-07-07

