中間件所作的事情就是在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]);