理解redux的中间件
export default function applyMiddleware(...middlewares) {
return (createStore) => (reducer, preloadedState, enhancer) => {
// 接收 createStore 参数
var store = createStore(reducer, preloadedState, enhancer)
var dispatch = store.dispatch
var chain = []
// 传递给中间件的参数
var middlewareAPI = {
getState: store.getState,
dispatch: (action) => dispatch(action)
}
// 注册中间件调用链,并由此可知,所有的中间件最外层函数接收的参数都是{getState,dispatch}
chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
中间件的一般形式
export default store => next => action => {console.log(1), next(action)}
compose 函数起到代码组合的作用:compose(f, g, h)(...args) 效果等同于 f(g(h(...args))),
此时 middleware已经传入了middlewareApi(也就是store),所以
middleware变成了 next => action => {console.log(1), next(action)}
假设f, g, h函数就是不同的中间件,符合middleware等式,而且他们层层嵌套,
所以f(g(h(...args)))相当于g(h(...args))入参next执行f函数得到了返回值
action => {console.log(1),g(h(...args))(action) 相当于 h(...args)入参next执行g函数得到返回值
action => {console.log(1), (action => {console.log(1), h(...args)(action)})(action) 匿名函数传入action
执行化简
action => {console.log(1),{console.log(1), h(...args)(action)}) 相当于...args入参next执行h函数
action => {console.log(1),{console.log(1), (action => {console.log(1), ...argu(action)})(action)}传入action执行化简
{console.log(1),{console.log(1),console.log(1),...argu(action)}...argu在compose中是store.dispatch,所以
{console.log(1),{console.log(1),console.log(1),store.dispatch(action)}
这样就把action发出去了,而且在发出之前中间件做了很多操作(eg:答应了了1),不难发现其实每一步的next就是下一层嵌套函数的执行结果也就是
action => {console.log(1), next(action)}直到最后一层store.dispath