中间件所作的事情就是在action发起后,到reducer以前作扩展,实现的方式是对store的dispatch进行包装app
store.dispatch => 【middlewales】 => return new store.dispatch函数
因此从上面所知,middlewales是须要接受store的dispatch为参数的,为了进行state的一些操做好比跟踪state变化,则把getState也一同传入spa
middlewales(store.dispatch,store.getState) = > return new dispatchcode
而后applyMiddleWales基本上作了一件事就是遍历了middlewales中间件
applyMiddleWales(store,[middlewals1,.....]) => return new store.dispatchblog
官网上也在实现上分了两步进行解释大体的实现get
第一部分:这个比较简单,就是把store传下去,而后把dispatch从新返回来,固然在这之间能够作些什么再返回来,好比添加log,捕获错误等it
const logger1 =(store) => { const next = store.dispatch return (action)=>{ console.log('log1---start') let o = next(action); console.log('log1---end') return o; } } const logger2 = (store) => { const next = store.dispatch; return (action) =>{ console.log('log2----start'); let o = next(action); console.log('log2-----end') return o; } } const store = { dispatch:()=>{console.log('dispatch----')} } function middle(store,wales){ wales.forEach(item => { store.dispatch = item(store) }) } middle(store,[logger1,logger2]) //打印: //log2 --start //log1--start //dispacht //log1--end //log2--end
第二步:这里把middlewales的调用方式改变了一下,前面是middle(store) => return dispatch,这里是middls(store)(dispatch) => return dispatchio
这么作的好处是否是直接在store身上直接去扩展dispatch,而是把dispatch从源头传出来,而后返回新的dispatch,最后生成的也是store的一个副本。console
const newLog1 = (store)=>{ return (next) => { return (action) =>{ console.log('newLog1---start') let o = next(action); console.log('newLog1---end'); return o; } } } const newLog2 = (store)=>{ return (next) => { return (action) =>{ console.log('newLog2---start') let o = next(action); console.log('newLog2---end'); return o; } } } newLog2(store);//此时这个返回的是一个函数,(next) => return (action)=>{} newLog2(store)(store.dispatch)//此时返回的是一个函数 (action)=>{} const newStore = { dispatch:() => console.log('newStore dispatch-----') } const newMiddle = (store,wales) =>{ let dispatch = store.dispatch; wales.forEach(item => { dispatch = item(store)(dispatch); }) return {...store,dispatch}; } const ns = newMiddle(newStore,[newLog1,newLog2]);