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

寫法一
首頁創(chuàng)建一個按鈕進行觸發(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
這里判斷傳來的值如果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狀態(tài)編寫
這里使用redux-saga中的createSagaMiddleWare
然后運行了任務(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
然后開始創(chuàng)建任務(wù)在saga.js中
- take:監(jiān)聽組件發(fā)來的action
- fork:同步執(zhí)行異步處理函數(shù)
- put:發(fā)出新的action
- call:發(fā)出異步請求
/**
* saga任務(wù)
*/
import {take,fork,put,call} from 'redux-saga/effects'
function *watchSaga(){
while(true){
//take 監(jiān)聽 組件發(fā)來的action
yield take("get-list")
//fork 同步執(zhí)行異步處理函數(shù)
yield fork(getList)
}
}
function *getList(){
//這里做異步處理的
//call函數(shù)發(fā)異步請求
let res= yield call(getListAction)//參數(shù)是返回值為promise對象的函數(shù)
//等待call執(zhí)行完才會執(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
然后導出給store進行使用
這樣一個流程就這樣走完了,從而實現(xiàn)第一次點擊頁面數(shù)據(jù)會執(zhí)行該任務(wù)并且給list1賦值,第二次點擊就可以直接拿到值了.over~
寫法二
將take與fork進行替換
只需要用到takeEvery
//原來:
function *watchSaga2(){
while(true){
//take 監(jiān)聽 組件發(fā)來的action
yield take("get-list2")
//fork 同步執(zhí)行異步處理函數(shù)
yield fork(getList2)
}
}
//現(xiàn)在:
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進行執(zhí)行~
到此這篇關(guān)于Redux saga異步管理與生成器詳解的文章就介紹到這了,更多相關(guān)Redux saga異步管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Remix集成antd和pro-components的過程示例
這篇文章主要為大家介紹了Remix集成antd和pro-components的過程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03
react-native-tab-navigator組件的基本使用示例代碼
本篇文章主要介紹了react-native-tab-navigator組件的基本使用示例代碼,具有一定的參考價值,有興趣的可以了解一下2017-09-09
React中路由參數(shù)如何改變頁面不刷新數(shù)據(jù)的情況
這篇文章主要介紹了React中路由參數(shù)如何改變頁面不刷新數(shù)據(jù)的情況,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08

