欢迎关注redux源码分析系列文章:
redux源码分析之一:createStore.js
redux源码分析之二:combineReducers.js
redux源码分析之三:bindActionCreators.js
redux源码分析之四:compose.js
redux源码分析之五:applyMiddlewareredux
redux中间件其实很是简单,中间件的目的只有一个:在dispatch先后,执行一些代码,达到加强dispatch的效果,有点相似装饰器的原理。segmentfault
applyMiddleware须要结合createStore函数来看,appleyMiddleware就是createStore的第三个参数enhancer,好比,对redux-logger中间件,其使用方式以下:api
import { applyMiddleware, createStore } from 'redux'; import { createLogger } from 'redux-logger'; const logger = createLogger(); const store = createStore( reducer, applyMiddleware(logger) )
applyMiddleware文件的源码以下:app
export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { const store = createStore(reducer, preloadedState, enhancer) let dispatch = store.dispatch let chain = [] const middlewareAPI = { getState: store.getState, dispatch: (...args) => dispatch(...args) } chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } }
函数的返回值自己,也是另一个函数,而这个函数,接受的参数是createStore,结合createStore的前几行源码来看:函数
export default function createStore(reducer, preloadedState, enhancer) { 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的第三个参数ehancer若是是一个函数的话,就会优先执行ehancer,而后再再enhancer内部调用createStore函数,因此,createStore其实只会执行一些,也只会生成一个store。源码分析
我添加了代码注释以下:(关于compose函数的解释,请参考文章:redux源码分析之四:compose.js):spa
export default function applyMiddleware(...middlewares) { return (createStore) => (reducer, preloadedState, enhancer) => { //这里会原封不动的执行createStore,并根据入参生成一个store const store = createStore(reducer, preloadedState, enhancer) //把dispatch从store中取出来 let dispatch = store.dispatch let chain = [] //这里约定了全部的redux中间件只能使用的api就是2个,getState和dispatch const middlewareAPI = { getState: store.getState, dispatch: (...args) => dispatch(...args) } 对每个中间件,执行中间件函数,并将中间件api对象传入函数,用chain变量接收中间件执行结果的其返回值 chain = middlewares.map(middleware => middleware(middlewareAPI)) //这里用到了compose函数,分别按顺序从后往前执行每个中间件,而且前一个中间件的返回值做为后一个中间件的入参,全部中间件的第一个入参是原始的store.dispatch dispatch = compose(...chain)(store.dispatch) //最后返回store对象,只是,使用了通过中间件加工过的dispatch对象,替换掉原始的dispatch对象 return { ...store, dispatch } } }
redux中间件只有一个目的:在dispatch先后,执行一些代码,达到加强dispatch的效果,有点相似装饰器的原理。,理解好了这一点就ok了。
下一篇文章会给你们带来一个最简单的redux中间件,敬请期待。code