const store = createStore( rootReducer, applyMiddleware( thunkMiddleware, // lets us dispatch() functions loggerMiddleware // neat middleware that logs actions ) )
其中applyMiddleware(...)
是一个enhancer。enhancer在redux中的做用会代理createStore方法返回具备加强效果的store.redux
applyMiddleware接收一系列middlewares。一个典型的middleware是长这样的:app
export default function thunkMiddleware({ dispatch, getState }) { return next => action => { if (typeof action === 'function') { return action(dispatch, getState); } return next(action); }; }
applyMiddleware
在接收到middleware后,会进行以下处理:函数
export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, initialState, enhancer) => { var store = createStore(reducer, initialState, enhancer) var dispatch = store.dispatch var chain = [] var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } // 将middleware初始化,些时chain里是Array<next=>action=>doSomething> chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } }
重点是后面的compose
语句。compose
的实现很是简单:spa
export default function compose(...funcs) { return (...args) => { if (funcs.length === 0) { return args[0] } const last = funcs[funcs.length - 1] const rest = funcs.slice(0, -1) return rest.reduceRight((composed, f) => f(composed), last(...args)) } }
接收一堆参数fns,返回另外一个函数。在这个函数里,将参数中的函数逐个从右到左执行,上一个执行的结果将作为下一个执行的参数。代理
即compose(f, g, h)(100)
至关于f(g(h(100)))
. 而对于上面的dispatch = compose(...chain)(store.dispatch)
,因为chain中的每个函数的结构均为:rest
function g(next) { return function (action) { // do something } }
对于函数g
,执行g(dispatch)
至关于返回一个函数:code
function (action) { // 这个函数中,next的值为dispatch }
所以,对于d = compose(f, g)(dispatch)
,即至关于返回了一个函数:get
这个函数长的是这样的: function f1(action) {/* 函数体中的next为g1*/}
it
g1
的定义是function g1(action) {/* 函数体中的next为dispatch*/}
io
这样经过调用d
,层层next
下去,最终就调到了dispatch了。
注:因为上面的chain = middlewares.map(middleware =>middleware(middlewareAPI))
,每个middleware都能直接访问到store.dispatch,每一个middleware均可以在任意时刻进行dispatch,之因此最后一个next被弄成了dispatch,可能只是为了让默认行为是dispatch.