@dlutwuwei
2016-09-22T05:22:46.000000Z
字数 1906
阅读 661
redux
redux中间件在action的dispatch过程中执行,这样我们就这样在这个过程中处理一下特殊情况或者做一些其他事情。比如截获一些ajax的action进行异步请求处理(redux-thunk), 在action级别记录用户日志等.
和nodejs上的流程处理方式类似,redux中间件使用了非常巧妙的链式执行的方法。
下面是一个典型的中间件结构,其返回的function称为thunk函数,参考thunk介绍
function thunkMiddleware({ dispatch, getState }, ...extraArgument) {//闭包 dispatch,getStatereturn next => action => {//链式执行的next结构if (typeof action === 'function') {return action(dispatch, getState, extraArgument);}return next(action);}};
下面看applyMiddleware的代码
export default function applyMiddleware(...middlewares) {return (createStore) => (reducer, preloadedState, enhancer) => {var store = createStore(reducer, preloadedState, enhancer)var dispatch = store.dispatchvar chain = []var middlewareAPI = {getState: store.getState,dispatch: (action) => dispatch(action)}//获取所有中间件的next结构function,存入chain中chain = middlewares.map(middleware => middleware(middlewareAPI))//闭包调用链dispatch = compose(...chain)(store.dispatch)return {...store,dispatch}}}
compose代码使用reduceRight生成调用链
export default function compose(...funcs) {if (funcs.length === 0) {return arg => arg}if (funcs.length === 1) {return funcs[0]}const last = funcs[funcs.length - 1]const rest = funcs.slice(0, -1)/*last(..args)生成第一个action => {}结构,最后面的中间件,args为外层调用时传入的store.dispatchf(composed)将前一个 action => { next(action) }结构,闭包进新生成的 next => action => { next(action) }结构,最终外层把store.dispatch闭包进最新的一个next => action => { next(action) }结构,并返回action => { next(action) },生成新的dispatch*/return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))}
last(..args)生成第一个 action => {}(thunk函数返回的)结构,最后面的中间件,args为外层调用时传入的store.dispatch, 即最后一个中间件使用的nextf(composed)将前一个thunk执行返回的composed即action => { next(action) }结构整个function闭包进新生成的 action => { next(action) }结构,action => { next(action) },生成新的dispatch