redux中间件源码分析(一)

2019-07-26  本文已影响0人  king_184f

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

首先说下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是在这个地方创建的,这里存在一个很隐蔽的递归调用,终于知道了(松了一口气)

上一篇下一篇

猜你喜欢

热点阅读