redux的中间件(middleware)

applyMiddleware的实现

首先我们来看下applyMiddleware源码实现,代码如下所示:

export default function applyMiddleware(...middlewares) {
  return (createStore) => (reducer, preloadedState, enhancer) => {
    var store = createStore(reducer, preloadedState, enhancer)
    var dispatch = store.dispatch
    var chain = []

    var middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    }
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

其中:
1、applyware执行完成后会返回一个闭包,该闭包接受的参数为createStore。这个闭包会在createStore方法中被执行。这样就可以在所有的middleware中共享store了。
2、compose方法会基于middlewares和store.dispatch生成一个新的dispatch。
3、最终用新生成的dispatch来替换store中原有的dispatch。
由上可知,其中最关键的也就是compose方法:

export default function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }

  if (funcs.length === 1) {
    return funcs[0]
  }

  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}

其中args参数为store.dispatch,而且每个middleware在定义时也可以接收dispatch参数,具体见中间件的结构。

参照文档可知,[0, 1, 2, 3, 4].reduce( (prev, curr) => prev + curr ) 的执行如下:
这里写图片描述
最后一次函数调用的返回值 (10) 作为reduce函数的结果被返回。

中间件的结构

中间件的结构如下:

function ({getState, dispatch}) {
    return function (next) {
        return function (action) {...}
    }
}

applyMiddleware中的middlewares.map执行后,中间件返回为:

function (next) {
        return function (action) {...}
    }

当compose执行完毕后,就会生成新的dispatch。在每个中间件中可以基于自己的判断,action是否交个下一个middleware去处理,还是自己处理完毕后直接调用dispatch。

中间件的执行过程

假设我们有3个中间件A、B、C,

A = ({dispatch}) => next => action => {
     if(conditionA){
     return dispatch(action)
     }
     return next(action);
}
B = ({dispatch}) => next => action => {
     if(conditionB){
     return dispatch(action)
     }
     return next(action);
}
C = ({dispatch}) => next => action => {
     if(conditionC){
     return dispatch(action)
     }
     return next(action);
}

则最终生成的dipatch类似与:

newDispatch = action => {
     if(conditionA){
         return dispatch(action)
     }
     return (action) => {
         if(conditionB){
            return dispatch(action)
          }
         return (action) => {
         if(conditionC){
            return dispatch(action)
          }
         return next(action); //这时,C中的next为store.dispatch
        }
}

这样,在中间件中就可以判断如何对action进行处理。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值