欢迎来到DIVCSS5查找CSS资料与学习DIV CSS布局技术!
最近在总结最近用的知识,好记性不如烂笔头,所以写出来记录下。
 
“It provides a third-party extension point between dispatching an action, and the moment it reaches the reducer.”
 
这是 Dan Abramov 对 middleware 的描述。它提供了一个分类处理 action 的机会。在 middleware 中,你可以检阅每一个流过的 action,挑选出特定类型的 action 进行相应操作,给你 一次改变 action 的机会。
 
应用 middleware 后 Redux 处理事件的逻辑
 
我们还是从实际出发,再来看下内部构造:
 
打印日志中间件
 
白名单中间件
 
applyMiddleware中间件的源码非常精炼,大约只有20多行。
 
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
 
    }
 
  }
 
}
 
看懂这段代码,需要提前了解函数式编程compose以及pipe思想,其实就是一个传参数据流,一个从右到左一个从左到右。我们带着问题去看这段代码,为什么我们平时写的时候要传入(store) => (next) => (action)这三个参数?
 
代码前几行创建了store,createStore后面三个参数是Redux原生createStore方法的标准参数。下面的middlewareAPI其实就是一个精简的store,并且提供了getState和dispach方法。
 
接下来来看compose,compose顾英文名思中国义即组合函数,将多个函数组合起来串联执行,一个函数的输出作为另一个函数的输入,一旦第一个函数开始执行,过程就会像多米诺骨牌。
 
let result = compose(f1, f2, f3, f4)(value); ====> let result = f1(f2(f3(f4(value))));
 
 chain = middlewares.map(middleware => middleware(middlewareAPI))
 
 dispatch = compose(...chain)(store.dispatch)
 
dispatch = compose(...chain)(store.dispatch)
 
可以变化为:
 
fnMiddle = fn(middlewareAPI);
 
dispatch = fnMiddle(store.dispatch)
 
最后等价于:
 
dispatch = fn(middlewareAPI)(store.dispatch)
 
接着:
 
store.dispatch(action)
 
等价于
 
fn(middlewareAPI)(store.dispatch)(action) == 对应middleware的三个参数store, next, action。
 
dispatch = compose(...chain)(store.dispatch) === dispatch= fn1Middle(fn2Middle(store.dispatch))
 
// fn1Middle = fn1(middlewareAPI)
 
首先执行的是fn2Middle(store.dispatch),返回结果是如下的一个函数。紧接着fn1Middle( (action) => {} ),这个action函数相当于占据了fn1中next参数的位置。在收到action参数之前呢函数并不会执行。
 
// fn2Middle(store.dispatch)执行后
 
(action) => {
 
    ....
 
    next(action)
 
    ....
 
}

如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h63311.shtml