老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業提供網站建設、域名注冊、服務器等服務

redux處理異步action的示例分析

小編給大家分享一下redux處理異步action的示例分析,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

為鳳翔等地區用戶提供了全套網頁設計制作服務,及鳳翔網站建設行業解決方案。主營業務為成都網站設計、網站制作、鳳翔網站設計,以傳統方式定制建設網站,并提供域名空間備案等一條龍服務,秉承以專業、用心的態度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

如果沒有中間件,store.dispatch只能接收一個普通對象作為action。在處理異步action時,我們需要在異步回調或者promise函數then內,async函數await之后dispatch。

dispatch({
  type:'before-load'
})
fetch('http://myapi.com/${userId}').then({
  response =>dispatch({
      type:'load',
      payload:response
    })
})

這樣做確實可以解決問題,特別是在小型項目中,高效,可讀性強。 但缺點是需要在組件中寫大量的異步邏輯代碼,不能將異步過程(例如異步獲取數據)與dispatch抽象出來進行復用。而采用類似redux-thunk之類的中間件可以使得dispatch能夠接收不僅僅是普通對象作為action。例如:

function load(userId){
  return function(dispatch,getState){
    dispatch({
      type:'before-load'
    })
    fetch('http://myapi.com/${userId}').then({
      response =>dispatch({
        type:'load',
        payload:response
      })
    })
  }  
}
//使用方式
dispatch(load(userId))

使用中間件可以讓你采用自己方便的方式dispatch異步action,下面介紹常見的三種。

1. redux-thunk

function createThunkMiddleware(extraArgument) {
 return ({ dispatch, getState }) => next => action => {
  if (typeof action === 'function') {
   return action(dispatch, getState, extraArgument);
  }

  return next(action);
 };
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

2. redux-promise

使用redux-promise可以將action或者action的payload寫成promise形式。 源碼:

export default function promiseMiddleware({ dispatch }) {
 return next => action => {
  if (!isFSA(action)) {
   return isPromise(action) ? action.then(dispatch) : next(action);
  }

  return isPromise(action.payload)
   ? action.payload
     .then(result => dispatch({ ...action, payload: result }))
     .catch(error => {
      dispatch({ ...action, payload: error, error: true });
      return Promise.reject(error);
     })
   : next(action);
 };
}

3. Redux-saga

redux-saga 是一個用于管理應用程序 Side Effect(副作用,例如異步獲取數據,訪問瀏覽器緩存等)的 library,它的目標是讓副作用管理更容易,執行更高效,測試更簡單,在處理故障時更容易

3.1 基本使用

import { call, put, takeEvery, takeLatest} from 'redux-saga/effects';

//復雜的異步流程操作
function* fetchUser(action){
 try{
  const user = yield call(API.fetchUser, action.payload);
  yield put({type:"USER_FETCH_SUCCEEDED",user:user})
 }catch(e){
  yield put({type:"USER_FETCH_FAILED",message:e.message})
 }
}

//監聽dispatch,調用相應函數進行處理
function* mainSaga(){
 yield takeEvery("USER_FETCH_REQUESTED",fetchUser);
}

//在store中注入saga中間件
import {createStore,applyMiddleware} from 'redux';
import createSagaMiddleware from 'redux-saga';

import reducer from './reducers';
import mainSaga from './mainSaga';
const sagaMiddleware = createSagaMiddleware();

const store = createStore(reducer,initalState,applyMiddleware(sagaMiddleware));

sagaMiddleware.run(mainSaga)

3.2 聲明式effects,便于測試

為了測試方便,在generator中不立即執行異步調用,而是使用call、apply等effects創建一條描述函數調用的對象,saga中間件確保執行函數調用并在響應被resolve時恢復generator。

function* fetchProducts() {
 const products = yield Api.fetch('/products')
 dispatch({ type: 'PRODUCTS_RECEIVED', products })
}

//便于測試
function* fetchProducts() {
 const products = yield call(Api.fetch, '/products')
 //便于測試dispatch
 yield put({ type: 'PRODUCTS_RECEIVED', products })
 // ...
}
// Effect -> 調用 Api.fetch 函數并傳遞 `./products` 作為參數
{
 CALL: {
  fn: Api.fetch,
  args: ['./products'] 
 }
}

3.3 構建復雜的控制流

saga可以通過使用effect創建器、effect組合器、saga輔助函數來構建復雜的控制流。

effect創建器:

  • take:阻塞性effect,等待store中匹配的action或channel中的特定消息。

  • put:非阻塞性effect,用來命令 middleware 向 Store 發起一個 action。

  • call:阻塞性effect,用來命令 middleware 以參數 args 調用函數 fn。

  • fork:非阻塞性effect,用來命令 middleware 以 非阻塞調用 的形式執行 fn

  • select:非阻塞性effect,用來命令 middleware 在當前 Store 的 state 上調用指定的選擇器

effect組合器:

race:阻塞性effect:用來命令 middleware 在多個 Effect 間運行 競賽(Race)

function fetchUsersSaga { 
 const { response, cancel } = yield race({ 
 response: call(fetchUsers), 
 cancel: take(CANCEL_FETCH) 
 }) 
}

all: 當 array 或 object 中有阻塞型 effect 的時候阻塞,用來命令 middleware 并行地運行多個 Effect,并等待它們全部完成

function* mySaga() { 
 const [customers, products] = yield all([ 
 call(fetchCustomers), 
 call(fetchProducts) 
 ]) 
}

effect輔助函數:

takeEvery:非阻塞性effect,在發起(dispatch)到 Store 并且匹配 pattern 的每一個 action 上派生一個 saga

const takeEvery = (patternOrChannel, saga, ...args) => fork(function*() { 
while (true) { 
const action = yield take(patternOrChannel) 
yield fork(saga, ...args.concat(action)) 
} 
  })

takeLatest:非阻塞性,在發起到 Store 并且匹配 pattern 的每一個 action 上派生一個 saga。并自動取消之前所有已經啟動但仍在執行中的 saga 任務。

 const takeLatest = (patternOrChannel, saga, ...args) => fork(function*() { 
  let lastTask 
  while (true) { 
  const action = yield take(patternOrChannel) 
  if (lastTask) { 
  yield cancel(lastTask) // 如果任務已經結束,cancel 則是空操作 
  } 
  lastTask = yield fork(saga, ...args.concat(action)) 
  } 
 })

throttle:非阻塞性,在 ms 毫秒內將暫停派生新的任務

const throttle = (ms, pattern, task, ...args) => fork(function*() { 
  const throttleChannel = yield actionChannel(pattern) 
   
  while (true) { 
  const action = yield take(throttleChannel) 
  yield fork(task, ...args, action) 
  yield delay(ms) 
  } 
  })

看完了這篇文章,相信你對“redux處理異步action的示例分析”有了一定的了解,如果想了解更多相關知識,歡迎關注創新互聯行業資訊頻道,感謝各位的閱讀!


新聞標題:redux處理異步action的示例分析
本文地址:http://www.xueling.net.cn/article/joodig.html

其他資訊

在線咨詢
服務熱線
服務熱線:028-86922220
TOP
主站蜘蛛池模板: 三年片中国在线观看免费大全 | 日韩人妻无码精品系列专区 | 亚洲一区二区入口 | 精品一区精品二区 | 91国产精品入口 | 91精彩视频在线观看 | 色狠狠色噜噜aⅴ天堂三区 麻豆久久久久久 | 葵司一区二区 | 国产精品亚洲无码在线 | 成人激情视频在线播放 | 很污网站 | 丰满人妻无奈张开双腿AV | 韩国精品在线 | 久久频这里精品99香蕉 | 深夜影院在线观看 | 成年人网址在线观看 | 中文字幕在线观看国产推理片 | 凤隐电视连续剧免费观看 | 挺进朋友人妻的身体里 | 欧美+国产+日产+韩国 | 曰韩无码AV片免费播放不卡 | 韩国三级中文字幕HD久久精品 | 亚洲超碰在线 | 久久伊人色AV天堂九九小黄鸭 | 国产1区在线观看 | 97一区二区三区 | 欧美精品一区二区三区视频 | 少妇高潮喷水正在播放 | 天天干夜夜春夜夜爽 | 欧美性人妖xxxxx极品 | 国产中文综合 | 男人捅女人免费视频 | 国产免费拔擦拔擦8x在线牛 | 国产精品露脸国语对白 | 久久久久久伊人高潮影院 | 夜夜躁狠狠躁日日躁2024 | 久久久精品视频成人 | 脱了内裤猛烈进入A片费 | 欧美乱子YELLOWVIDEO | 久久99精品国产99久久6尤物 | 国产1区在线观看 |