//調用
const store = createStore(rootReducer, applyMiddleware(...middlewares));
//createStore
export default function createStore(reducer, preloadedState, enhancer) //若是第二個參數是function,而且沒傳第三個參數,則將第二個參數賦值給第三個參數,而後將第二個參數設爲undefined if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
enhancer = preloadedState
preloadedState = undefined
}
if (typeof enhancer !== 'undefined') {
if (typeof enhancer !== 'function') {
throw new Error('Expected the enhancer to be a function.')
}
//返回一個高階函數
return enhancer(createStore)(reducer, preloadedState)
}
}
複製代碼
經過調用createStore 返回的結果能夠解析爲javascript
applyMiddleware(...middlewares)(createStore)(reducer, initialState)
複製代碼
//調用applyMiddleware,能夠傳入多箇中間件
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, initialState, enhancer) => {
var store = createStore(reducer, initialState, enhancer)
var dispatch = store.dispatch
var chain = []
//將state和dispatch所指向的函數綁定到middlewareAPI
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
//迭代中間件數組,並執行一遍,將middlewareAPI做爲最外層的store,並返回一個至關於next函數的數組
chain = middlewares.map(middleware => middleware(middlewareAPI))
//將數組整理成嵌套的函數體,並將store.dispatch傳入最內側的函數的next,並返回通過處理的dispatch
//dispatch是一個函數,是一個嵌套了多層的函數,其最裏面調用的是store.dispatch
dispatch = compose(...chain)(store.dispatch)
//返回一個新的store
return {
...store,
dispatch
}
}
}
複製代碼
大體看下,其實就是經過一些操做,而後返回一個通過處理的store,dispatchjava
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
複製代碼
export default function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
複製代碼
這裏有必要解釋下funcs.reduce((a, b) => (...args) => a(b(...args))) 這一坨作了些什麼?redux
reduce 是專門爲累加操做設計的,啥意思呢數組
先把funcs.reduce((a, b) => (...args) => a(b(...args))) 翻譯一下app
//以redux-saga爲例
//看參數,就知道爲何定義middlewareAPI對象了
function sagaMiddleware({ getState, dispatch }) {
...
return next => action => {
if (sagaMonitor && sagaMonitor.actionDispatched) {
sagaMonitor.actionDispatched(action)
}
const result = next(action) // hit reducers
channel.put(action)
return result
}
}
複製代碼
//模擬三個middleware
function A(next){
return function A1(action){
next(action)
}
}
function B(next){
return function B1(action){
next(action)
}
}
function C(next){
return function C1(action){
next(action)
}
}
複製代碼
假設 dispatch = A(B(C(store.dispatch))),開始執行函數
function A1(action){
function B1(action){
return function C1(action){
store.dispatch(action)
}
}
}(action)
複製代碼
一個action的執行順序:A(action) -> B(action) -> C(action) -> store.dispatch(action),先從內到外生成新的func,而後由外向內執行.ui