说明:对Redux不了解的同窗可先看看这篇文章Redux技术架构简介(一)html
这里说的Redux异步实现,是专指Redux中的异步Action实现,而不是指应用的异步实现,由于Redux自己只支持同步action,即发送action,state当即更新;那若是我在发送一个action后,须要state过一段时间再更新呢?按正常的思路redux是没法处理这种状况的,下面就来看看异步Action是如何实现的吧!react
须要提的一点是,其实彻底能够将异步逻辑写在View中,而后在回调函数中发送action。可是若是你要配合react一块儿使用,这样作就违背了react-redux的设计思想,即UI与逻辑的分离(具体的实现能够在下一篇文章中看到),并且当存在多个异步请求时也很难将异步逻辑抽象出来,因此异步逻辑应该由Redux架构实现,这样也就必须实现发送异步action了npm
为了解决上面提到的问题,咱们须要引入中间件的概念。json
中间件执行的时机是在action发起以后,reducer执行以前。redux
本质上,中间件就是对dispatch函数的改造。当执行dispatch(action)时,会先调用中间件,进行一些内部逻辑处理,如:添加日志等,以后再执行dispatch。若是要支持中间件的链式调用,必须再返回一个dispatch。
下面是中间件的简单实现:bash
function logger(store) {
// 这里的 next 必须指向前一个 middleware 返回的函数:
const next = store.dispatch
return function dispatchAndLog(action) {
console.log('dispatching', action)
let result = next(action)
console.log('next state', store.getState())
return result
}
}
复制代码
可使用Redux的API—applyMiddleware直接使用中间件,代码以下:架构
import {applyMiddleware,createStore} from 'redux';
import {createLogger} from 'redux-logger';//log中间件
import thunk from 'redux-thunk';//将dispatch改形成能够接受函数做为参数的中间件
import indexPhotomainReducer from '../reducer/indexPhotomainReducer';
const logger = createLogger();
const store = createStore(
indexPhotomainReducer,
applyMiddleware(thunk, logger)
);
复制代码
因而可知,能够把applyMiddleware做为createStore的第二个参数传入,你所使用的中间件须要下载单独npm包,而后按顺序传入applyMiddleware函数中(注:中间件有顺序要求,须要看下每一个中间件的使用文档,logger通常要放在最后)。app
须要增长三种action异步
示例代码以下:ide
export const requestPostsAction = () => {
return {
type: REQUEST_POSTS
};
}
export const receivePostsSuccessAction = (data) => {
return {
type: RECEIVE_POSTS_SUCCESS,
data
};
}
export const receivePostsFailureAction = (error) => {
return {
type: RECEIVE_POSTS_FAILURE,
error
};
}
复制代码
返回参数彻底能够自定义。这3种action分别在请求开始前,请求成功后,请求失败后发送。
为了配合异步Action,能够在state树中增长2个属性:
State属性能够凭本身喜爱随意设计。设计好后能够这样编写reducer:
let sliderReducer = function (state = initialState, action) {
switch(action.type){
case photomainAction.RECEIVE_POSTS_SUCCESS:
return Object.assign({}, state, {photoData,videoData,isFetching:false,isValidate:true});
case photomainAction.RECEIVE_POSTS_FAILURE:
return Object.assign({}, state, {isFetching:false,isValidate:false});
case photomainAction.REQUEST_POSTS:
return Object.assign({}, state, {isFetching:true,isValidate:false});
default:
return state;
}
}
复制代码
当设计好action和state后,咱们想要达到的效果是--能够像同步同样dispatch一个action,而不用考虑异步逻辑。
为了达到这种效果,首先面临的问题是,异步逻辑放在哪里?这里只有2个选择:action中或reducer中(store是不适合处理数据的)。因为reducer必须是一个纯函数,他不适合处理像异步请求这样存在不肯定的输出的逻辑。最后只能放在action中处理了。
这时,为了处理异步请求,action建立函数须要返回一个带有异步请求逻辑的函数,而不是一个对象了。而dispatch只能接受对象,不能接受函数做为参数,这样就面临又一个问题:如何让dispatch接受函数?
接下来就是redux-thunk中间件发挥做用的时候了,他可让dispatch接受一个函数(原理就是上一节讲的,他实际上是改写了dispatch函数),最终异步的action能够这样实现:
//定义一个action creator – fetchPosts
export const fetchPosts = () => (dispatch, getState) => {
dispatch(requestPostsAction());
return window.fetch("/photo/initPage").then(response=>{
if(response.ok){
return response.json();
}else{
dispatch(receivePostsFailureAction("error"));
}
}).then(data => {
if(data){
dispatch(receivePostsSuccessAction(data));
}else{
dispatch(receivePostsFailureAction("error"));
}
});
}
复制代码
这样就能够像同步同样发送action了,即:
dispatch(fetchPosts());
复制代码
接下来只需静静等待view的更新就好了,这样就实现了整个Redux的异步流程。
本篇到此告一段落,下一篇介绍React与Redux整合技术。