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.