[关闭]
@dlutwuwei 2016-09-22T05:22:46.000000Z 字数 1906 阅读 661

redux中间件分析

redux


redux中间件在action的dispatch过程中执行,这样我们就这样在这个过程中处理一下特殊情况或者做一些其他事情。比如截获一些ajax的action进行异步请求处理(redux-thunk), 在action级别记录用户日志等.

和nodejs上的流程处理方式类似,redux中间件使用了非常巧妙的链式执行的方法。

下面是一个典型的中间件结构,其返回的function称为thunk函数,参考thunk介绍

  1. function thunkMiddleware({ dispatch, getState }, ...extraArgument) {
  2. //闭包 dispatch,getState
  3. return next => action => {
  4. //链式执行的next结构
  5. if (typeof action === 'function') {
  6. return action(dispatch, getState, extraArgument);
  7. }
  8. return next(action);
  9. }
  10. };

下面看applyMiddleware的代码

  1. export default function applyMiddleware(...middlewares) {
  2. return (createStore) => (reducer, preloadedState, enhancer) => {
  3. var store = createStore(reducer, preloadedState, enhancer)
  4. var dispatch = store.dispatch
  5. var chain = []
  6. var middlewareAPI = {
  7. getState: store.getState,
  8. dispatch: (action) => dispatch(action)
  9. }
  10. //获取所有中间件的next结构function,存入chain中
  11. chain = middlewares.map(middleware => middleware(middlewareAPI))
  12. //闭包调用链
  13. dispatch = compose(...chain)(store.dispatch)
  14. return {
  15. ...store,
  16. dispatch
  17. }
  18. }
  19. }

compose代码使用reduceRight生成调用链

  1. export default function compose(...funcs) {
  2. if (funcs.length === 0) {
  3. return arg => arg
  4. }
  5. if (funcs.length === 1) {
  6. return funcs[0]
  7. }
  8. const last = funcs[funcs.length - 1]
  9. const rest = funcs.slice(0, -1)
  10. /*
  11. last(..args)生成第一个action => {}结构,最后面的中间件,args为外层调用时传入的store.dispatch
  12. f(composed)将前一个 action => { next(action) }结构,
  13. 闭包进新生成的 next => action => { next(action) }结构,
  14. 最终外层把store.dispatch闭包进最新的一个next => action => { next(action) }结构,
  15. 并返回action => { next(action) },生成新的dispatch
  16. */
  17. return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))
  18. }
  1. last(..args)生成第一个 action => {}(thunk函数返回的)结构,最后面的中间件,args为外层调用时传入的store.dispatch, 即最后一个中间件使用的next
  2. f(composed)将前一个thunk执行返回的composed即action => { next(action) }结构整个function闭包进新生成的 action => { next(action) }结构,
  3. 最终返回第一个中间件的action => { next(action) },生成新的dispatch
  4. 执行的时候,每次调用next,就会执行后一个中间件的代码,并执行到后一个中间件的next时,又会触发下一个中间件的执行,具体见下图
Created with Raphaël 2.1.2redux middlewarem1m1m2m2m3m3m4m4disptchdisptchbefore nextbefore nextbefore nextbefore nextstore.disptach finishedafter nextafter nextafter nextafter nextnew dispatch finished
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注