站长网_站长创业_站长主页_站长之家_易采站长站

会员投稿 投稿指南 站长资讯通告: JS实现网页时钟特效
搜索:
您的位置: 主页 > 教程 > 网页编程 > JavaScript > » 正文

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)


            
最新图文资讯
1 2 3 4 5 6
易采站长站 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助 -