淘先锋技术网

首页 1 2 3 4 5 6 7

首先,个人比较少些文章,可能文笔不太好,请勿喷,第二,本文仅限于个人理解,如果异议,欢迎一同探讨QQ:251801008

接下来还会写其他相关的文章

首先我们可以看到redux源码目录下的源码主要只有6个文件

在utils包下面的是一个工具类,用来抛出错误警告

我们主要关注的是applyMiddleware,bindActinCreators,combineReducers,compose,createStore,index这几个文件

我们先从index入口文件开始,这个入口文件比较简单,就是将其他的5个JS文件进行导出。

我们一般使用redux是怎么使用的呢? 

eg: 

const store = createStore(
  combineReducers({ ...reducers }),
  initialState,
  enhancer
);

我们一般使用createStore来进行创建store。

现在我们来看看createStore到底做了什么事情。

首先我们看看这函数的入参,入参有3个 reducer, preloadedState, enhancer。

我们先来讲讲这3个参数分别是干什么用的

reducer:这个是redux流程中我们写的处理action的reducer的处理函数

preloadedState:这个就是初始化的state

enhancer:这个是createStore的增强器。

上面的参数接着往下走

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.')
  }

  return enhancer(createStore)(reducer, preloadedState)
}

if (typeof reducer !== 'function') {
  throw new Error('Expected the reducer to be a function.')
}

这一段代码是对于入参的类型判断,这里有一个地方需要注意,如果存在enhancer,那么将执行enhancer,后面代码将不会执行

let currentReducer = reducer
let currentState = preloadedState
let currentListeners = []
let nextListeners = currentListeners
let isDispatching = false

这里是对于入参的缓存,和定义一些局部变量。也比较简单

function ensureCanMutateNextListeners() {
  if (nextListeners === currentListeners) {
    nextListeners = currentListeners.slice()
  }
}

这个函数主要是确保nextListernners 和 currentListnerers 不是同一个内存地址,但是数据是一样的。

function getState() {
  return currentState
}

这个获取state状态树

function subscribe(listener) {
  if (typeof listener !== 'function') {
    throw new Error('Expected listener to be a function.')
  }

  let isSubscribed = true

  ensureCanMutateNextListeners()
  nextListeners.push(listener)

  return function unsubscribe() {
    if (!isSubscribed) {
      return
    }

    isSubscribed = false

    ensureCanMutateNextListeners()
    const index = nextListeners.indexOf(listener)
    nextListeners.splice(index, 1)
  }
}

subscribe方法主要是用来添加一个监听。

这里会将你传入的函数push到nextListeners,并且返回一个unsubScribe函数来进行监听的移除。

不知道什么原因贴图不显示了。。。就用文本了

function dispatch(action) {
  if (!isPlainObject(action)) { // 判断actions是不是个对象
    throw new Error(
      'Actions must be plain objects. ' +
      'Use custom middleware for async actions.'
    )
  }

  if (typeof action.type === 'undefined') { // 判断action中是否包含type
    throw new Error(
      'Actions may not have an undefined "type" property. ' +
      'Have you misspelled a constant?'
    )
  }

  if (isDispatching) { // isDispatching在开始的时候有进行定义, isDispatching = false
    throw new Error('Reducers may not dispatch actions.')
  }

  try {
    isDispatching = true
    currentState = currentReducer(currentState, action) // 执行reducer
  } finally {
    isDispatching = false
  }

  const listeners = currentListeners = nextListeners // 将nextListeners赋值给currentListeners,listeners
  for (let i = 0; i < listeners.length; i++) { // 循环遍历listeners,
    const listener = listeners[i] // 取出数组对应的监听
    listener() // 执行监听
  }

  return action // 返回action
}

 

function replaceReducer(nextReducer) { // 用来替换reducer
  if (typeof nextReducer !== 'function') {
    throw new Error('Expected the nextReducer to be a function.')
  }

  currentReducer = nextReducer
  dispatch({ type: ActionTypes.INIT }) // 重新构建初始化的state树
}

observable 这个是redux 一个观察者的模式

function observable() {
  const outerSubscribe = subscribe
  return {
    /**
     * The minimal observable subscription method.
     * @param {Object} observer Any object that can be used as an observer.
     * The observer object should have a `next` method.
     * @returns {subscription} An object with an `unsubscribe` method that can
     * be used to unsubscribe the observable from the store, and prevent further
     * emission of values from the observable.
     */
    subscribe(observer) {
      if (typeof observer !== 'object') {
        throw new TypeError('Expected the observer to be an object.')
      }

      function observeState() {
        if (observer.next) {
          observer.next(getState())
        }
      }

      observeState()
      const unsubscribe = outerSubscribe(observeState)
      return { unsubscribe }
    },

    [$$observable]() {
      return this
    }
  }
}
return {
  dispatch,
  subscribe,
  getState,
  replaceReducer,
  [$$observable]: observable
}

在最后将需要用到的API返回。