美文网首页
Redux中间件原理解析

Redux中间件原理解析

作者: Yezzle | 来源:发表于2020-03-08 20:31 被阅读0次

    redux项目开发过程中,有时候我们需要自己去编写一些redux中间件, 但是中间件用法法一般都像下面这样子:

    export function myMidware ({dispatch, getState}) {
        //  返回一个接收dispatch为参数的函数
        return (dispatch) => (action) => {
            // do something
            return dispatch(action)
        }
    }
    
    //使用中间件
    const store = createStore(reducer, applyMiddleware(myMidware))
    

    一看到这种套娃的写法,整个人都是懵的。那么接下来我就带着问题给大家理解理解, 为什么中间件函数非要这么写, applyMiddleware究竟做了什么

    废话不多说首先来看看applyMiddleware的源码,看看它到底做了啥:

    // 首先这个函数接收多个中间件函数,放在middlewares的数组中
    export default function applyMiddleware(...middlewares) {
      // 返回一个接受createStore参数的函数, 这个函数执行之后应该返回一个增强版createStore函数
      // (...args) => { ... } 这里可以看成是一个增强版的createStore函数(从createStore源码可以看出)
      return createStore => (...args) => {
        const store = createStore(...args)
        // 这里的dispatch是不希望你在创建中间件的时候调用它
        let dispatch = () => {
          throw new Error(
            'Dispatching while constructing your middleware is not allowed. ' +
              'Other middleware would not be applied to this dispatch.'
          )
        }
    
        // 把原版store的api构造成对象准备传递给中间件
        const middlewareAPI = {
          getState: store.getState,
          dispatch: (...args) => dispatch(...args) // 个人感觉这里不给用 其实就没必要给到中间件构造函数里面去
        }
        // 把构造好的api对象传递给中间件,让中间件拥有可以访问store的能力
        const chain = middlewares.map(middleware => middleware(middlewareAPI))
        // compose函数可以把多个中间件函数的数组,合成一个中间件函数的形式,然后再执行中间件
        // 并将得到的新的函数 当作新的dispatch函数
        dispatch = compose(...chain)(store.dispatch)
        // 返回一个增强了dispatch函数的store
        return {
          ...store,
          dispatch
        }
      }
    }
    

    从上面的代码解读可以看出, applyMiddleware函数,做了已下事情:

    • 返回一个新的createStore函数,这里叫它 superCreateStore函数
    • supterCreateStore函数中,执行了createStore函数,可见 args其实就是reducer,看createStore函数源码可知传入的就是reducer
    • superCreateStore函数中执行中间件函数,得到了一个新的dispatch函数,这里叫它superDispatch
    • 最后supterCreateStore函数返回了一个新的store对象,这个对象改造了dispatch函数

    看完了源码,接下来就开始理解这个思路了,套娃开始:

    首先是applyMiddleware

    • createStore( reducer, enhancer) 返回一个 store
    • applyMiddleware(...middleWares) 返回 enhancer增强器
    • enhencer就是一个函数,接收 createStore为参数,返回一个superCreateStore函数
    • superCreateStore函数和createStore一样,接手reducers作为参数,返回一个新的store

    再来理解中间件函数执行过程

    • superCreateStore 中,第一次执行中间传入了 middlewareAPI, 得到了dispatch增强器
    • dispatch增强器通过compose组合后,还是个dispatch增强器,再执行传入store.dispatch,也就是store原本的dispatch函数作为参数 得到了superDispatch函数

    到此我们就已经完全理解了中间件的执行过程及其作用,其实就是返回了一个dispatch增强器函数的函数,得到的增强器函数接收dispatch返回一个新的dispatch 函数,dispatch执行后会返回action,就是这样的逻辑, 这样我们就可以在actiondispatchstore之前,做一些处理。


    compose函数正是一个链式调用dispatch增强器的函数,每次执行一个函数都会返回一个增强过的dispatch函数,给下一个中间件, 下面贴一下compose函数的代码, 感兴趣的可以理解一下:

    export default function compose(...funcs) {
      if (funcs.length === 0) {
        return arg => arg
      }
    
      if (funcs.length === 1) {
        return funcs[0]
      }
      // 这里的args就是dispatch
      return funcs.reduce((a, b) => (...args) => a(b(...args)))
    }
    

    传送门

    相关文章

      网友评论

          本文标题:Redux中间件原理解析

          本文链接:https://www.haomeiwen.com/subject/wyejdhtx.html