美文网首页
redux中间件源码分析(一)

redux中间件源码分析(一)

作者: king_184f | 来源:发表于2019-07-26 14:05 被阅读0次

    废话不多说,直接上干货:

    首先说下middleware怎么用

     store = createStore(reducer, applyMiddleware(middleware, middleware2));
    

    下面先来看createStore里面干了什么,直接上源码(去除了里面的方法)

    export default function createStore(reducer, preloadedState, enhancer) {
    
      if (
    
        (typeof preloadedState === 'function' && typeof enhancer === 'function') ||
    
        (typeof enhancer === 'function' && typeof arguments[3] === 'function')
    
      ) {
    
        throw new Error(
    
          'It looks like you are passing several store enhancers to ' +
    
            'createStore(). This is not supported. Instead, compose them ' +
    
            'together to a single function.'
    
        )
    
      }
    //这里主要做了一下参数处理,让enhancer正确指向applyMiddleware返回的函数
      if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
    
        enhancer = preloadedState
    
        preloadedState = undefined
    
      }
    
      if (typeof enhancer !== 'undefined') {
    
        if (typeof enhancer !== 'function') {
    
          throw new Error('Expected the enhancer to be a function.')
    
        }
        //这里直接调用了applyMiddleware返回方法
        return enhancer(createStore)(reducer, preloadedState)
    
      }
    
      if (typeof reducer !== 'function') {
    
        throw new Error('Expected the reducer to be a function.')
    
      }
    
      let currentReducer = reducer
    
      let currentState = preloadedState
    
      let currentListeners = []
    
      let nextListeners = currentListeners
    
      let isDispatching = false
    //没有使用中间件的话直接返回store
      return {
    
        dispatch,
    
        subscribe,
    
        getState,
    
        replaceReducer,
    
        [$$observable]: observable
    
      }
    }
    

    看了上面createStore的源码,我们有两个结论:
    1.在没有使用中间件的时候,我们的createStore直接返回了一个store对象
    2.在使用了中间件的时候我们的createStore直接调用了applyMiddleware返回的方法
    问题:
    在使用中间件的时候store在哪创建的?
    别着急,下面我们来看applyMiddleware里面做了什么

    export default function applyMiddleware(...middlewares) {
      return createStore => (...args) => {
        const store = createStore(...args)
        let dispatch = () => {
          throw new Error(
            'Dispatching while constructing your middleware is not allowed. ' +
              'Other middleware would not be applied to this dispatch.'
          )
        }
    
        const middlewareAPI = {
          getState: store.getState,
          dispatch: (...args) => dispatch(...args)
        }
        const chain = middlewares.map(middleware => middleware(middlewareAPI))
        dispatch = compose(...chain)(store.dispatch)
    
        return {
          ...store,
          dispatch
        }
      }
    }
    

    果然applyMiddleware返回一个方法(这里是一个柯里化的写法)
    在上面我们说过在使用中间件的时候createStore执行的是一个applyMiddleware返回的方法,
    并传入了两个参数

    return enhancer(createStore)(reducer, preloadedState)
    return createStore => (...args) => {}
    

    再结合源码,都对上了此时createStore对应的是上面传进来的createStore,...args对应的是上面传入的
    (reducer, preloadedState)
    接着看这里

      //这个时候再调用createStore由于第二个参数不是一个方法,而且也不存在第三个参数,所以直接返回了store
    const store = createStore(...args)
    

    原来store是在这个地方创建的,这里存在一个很隐蔽的递归调用,终于知道了(松了一口气)

    相关文章

      网友评论

          本文标题:redux中间件源码分析(一)

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