关于javascript:redux源码解析之中间件

37次阅读

共计 2280 个字符,预计需要花费 6 分钟才能阅读完成。

redux 源码解析之中间件

了解中间件

简略来说,中间件就是对 store 的 dispatch 办法进行包装扩大。
它在 dispatch action 和达到 reducer 的那一刻之间提供了逻辑插入点。能够应用 Redux 中间件进行日志记录、异样监控、与异步 API 对话、路由等。
具体能够见官网文档 Middleware 中间件 | Redux 中武官网

具体实现

在 redux 中常见的中间件写法为

function middleWare({getState,dispatch}) {
  return next => action => {
       // xxx   
    return next(action)
   }
}

咱们能够看到这里屡次应用到高阶函数,看起来很简单,上面咱们来对他进行逐渐的解析。为了不便标记,我这里将箭头函数,改成函数申明的模式

function middleWare1({getState, dispatch}) {return function nextHandle1(next) {return function actionHandle1(action) {
         //xxx
      return next(action)
    }
  }
}

上面就开始解说 middleware nextHandle actionHandle 的具体应用场景

applyMiddleware

首先从入口讲起,常见的应用中间件的形式如下
const store = createStore(reducer, applyMiddleware([thunk, logger]));
能够看出,咱们是通过 applyMiddleware 办法将中间件办法包了一层。那么对应的 applyMiddleware 办法中解决中间件的流程为:

export default function applyMiddleware(...middlewares: Middleware[]
) {
// 省略局部代码
  const middlewareAPI: MiddlewareAPI = {
    getState: store.getState,
    dispatch: (action, ...args) => dispatch(action, ...args)
  }
 // 调用 middleware 办法,并传参
  const chain = middlewares.map(middleware => middleware(middlewareAPI))
// 外围逻辑 将函数按序组合 compose(a, b, c)(dispatch) => a(b(c(dispatch)))
  dispatch = compose<typeof dispatch>(...chain)(store.dispatch)
  return {
    ...store,
    dispatch
  }
}
// 简化 compose 函数实现
export default function compose(...funcs: Function[]) {return funcs.reduce(function(preFnA, itemFnB){return function (...args) {return preFnA(itemFnB(...args));
      }
  });
}

通过下面两行外围代码 middlewares.map 以及 dispatch = compose(xxx),咱们能够剖析失去 middlewares 本质上是在对原有的 dispatch 进行改写增强。
对应的咱们之前写的 middleWare1 函数在此处被调用,那么就成了

const chain = middlewares.map(middleware => middleware(middlewareAPI))
// middlewares 在调用 map 办法后就成了
const chain = [nextHandle1, nextHandle2,...]

dispatch = compose<typeof dispatch>(...chain)(store.dispatch)
// chain 中函数再次被 compose 组合,那么就成了
dispatch = actionHandle1(actionHandle2(actionHandle3(store.dispatch)))
dispatch = function actionHandle1(action){console.log('start1')
   const result = next(action);// 此处的 next 函数即 nextHandle2 中的 actionHandle2
   console.log('end1')
   return result 
}
function actionHandle2(action){console.log('start2')
   const result = next(action); // 此处的 next 函数即 actionHandle3
   console.log('end2')
   return result 
}
function actionHandle3(action){console.log('start3')
   const result = next(action); // 此处的 next 函数即 store.dispatch
   console.log('end3')
   return result 
}

实际上在 middlewares 调用过程中,能够用洋葱模型 (面向切面编程(AOP)) 来形容

上述代码在执行过程中会顺次打印 start1=> start2 =>start3 =>end3=> end2 =>end1。
最两头的那一层就是原始的 store.dispatch(action), 其余包裹它的中间件,都是对 dispatch 的增强

总结

到这里,构造就比拟清晰明了了,能够用一个图来概括

正文完
 0