中间件所做的事情就是在action发起后,到reducer之前做扩展,实现的方式是对store的dispatch进行包装
store.dispatch => 【middlewales】 => return new store.dispatch
所以从上面所知,middlewales是需要接受store的dispatch为参数的,为了进行state的一些操作比如跟踪state变化,则把getState也一同传入
middlewales(store.dispatch,store.getState) = > return new dispatch
然后applyMiddleWales基本上做了一件事就是遍历了middlewales
applyMiddleWales(store,[middlewals1,.....]) => return new store.dispatch
官网上也在实现上分了两步进行解释大致的实现
第一部分:这个比较简单,就是把store传下去,然后把dispatch重新返回来,当然在这之间可以做些什么再返回来,比如添加log,捕获错误等
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 dispatch
这么做的好处是不是直接在store身上直接去扩展dispatch,而是把dispatch从源头传出来,然后返回新的dispatch,最后生成的也是store的一个副本。
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]);