应用了以下的中间件: [A, B, C],git
整个执行 action 的过程为 A -> B -> C -> dispatch -> C -> B -> Agithub
==通过applyMiddleware
方法后的dispatch
方法是相似下面,某处调用store.dispatch则传入action, 而后按洋葱模型来执行==redux
(action) => { //... next(action) //... }
==最右侧的 next(action)
返回的是应用传入的action
==, 该行为是由redux createStore源码中dispatch方法返回值决定的,不过通常都会 return next(action)
,数组
前面的中间件的next(action)
的值都是后一个中间件的返回值闭包
const middleware1 = ({getState, dispatch}) => next => action => { console.log(`middleware1 before next action `) console.log(next) next(action) console.log(`middleware1 after next action `) } const middleware2 = ({getState, dispatch}) => next => action => { console.log(`middleware2 before next action `) console.log(next) next(action) console.log(`middleware2 after next action `) } const middleware3 = ({getState, dispatch}) => next => action => { console.log(`middleware3 before next action `) console.log(next) next(action) console.log(`middleware3 after next action `) } const sagaMiddleware = createSagaMiddleware() const store = createStore(reducer, applyMiddleware(middleware1, middleware2, middleware3))
是相似于func1(func2(store.dispatch))
这种形式的函数app
==next方法实际上是此中间件右边中间件的这个方法,你要给它传action。==函数
(action) => { //func2中的next是store.dispatch next(action); }
==实际的调用顺序是和传入中间件顺序相反的==spa
let store = applyMiddleware(Middleware1,Middleware2,Middleware3)(createStore)(rootReducer); 实际的执行是次序是store.dispatch->Middleware3->Middleware2->Middleware1。
var middlewareAPI = {3d
getState: store.getState, dispatch: (action) => dispatch(action)
};rest
并无直接使用dispatch:dispatch,而是使用了dispatch:(action) => dispatch(action),其目的是==若是使用了dispatch:dispatch,那么在全部的Middleware中实际都引用的同一个dispatch(闭包),若是存在一个中间件修改了dispatch,就会致使后面一下一系列的问题==,可是若是使用dispatch: (action) => dispatch(action)
就能够避免这个问题。
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) return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args)) }
这里chain是函数数组。而后执行compose(...chain)(store.dispatch)。
chain数组的最后一个函数接收store.dispatch函数作为参数,仍是返回一个函数,接收action做为参数。这个返回的函数是chain中倒数第二个函数的参数,也就是参数next
[ next => action => { return next(action) } ]
export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { var store = createStore(reducer, preloadedState, enhancer) var dispatch = store.dispatch var chain = [] var middlewareAPI = { getState: store.getState, dispatch: (action) => dispatch(action) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } }
function createThunkMiddleware(extraArgument) { return ({ dispatch, getState }) => next => action => { if (typeof action === 'function') { return action(dispatch, getState, extraArgument); } return next(action); }; } const thunk = createThunkMiddleware(); thunk.withExtraArgument = createThunkMiddleware; export default thunk;
https://github.com/MrErHu/blo...