createStore

  1. function createStore(reducer, preloadedState, enhancer) {
  2. if(enhancer是有效的){ // 这个我们后面会解释,可以先忽略
  3. return enhancer(createStore)(reducer, preloadedState)
  4. }
  5. let currentReducer = reducer // 当前store中的reducer
  6. let currentState = preloadedState // 当前store中存储的状态
  7. let currentListeners = [] // 当前store中放置的监听函数
  8. let nextListeners = currentListeners // 下一次dispatch时的监听函数
  9. // 注意:当我们新添加一个监听函数时,只会在下一次dispatch的时候生效。
  10. //...
  11. // 获取state
  12. function getState() {
  13. //...
  14. }
  15. // 添加一个监听函数,每当dispatch被调用的时候都会执行这个监听函数
  16. function subscribe() {
  17. //...
  18. }
  19. // 触发了一个action,因此我们调用reducer,得到的新的state,并且执行所有添加到store中的监听函数。
  20. function dispatch() {
  21. //...
  22. }
  23. //...
  24. //dispatch一个用于初始化的action,相当于调用一次reducer
  25. //然后将reducer中的子reducer的初始值也获取到
  26. //详见下面reducer的实现。
  27. return {
  28. dispatch,
  29. subscribe,
  30. getState,
  31. //下面两个是主要面向库开发者的方法,暂时先忽略
  32. //replaceReducer,
  33. //observable
  34. }
  35. }
  36. function getState() {
  37. return currentState
  38. }
  39. function subscribe(listener) {
  40. // 添加到监听函数数组,
  41. // 注意:我们添加到了下一次dispatch时才会生效的数组
  42. nextListeners.push(listener)
  43. let isSubscribe = true //设置一个标志,标志该监听器已经订阅了
  44. // 返回取消订阅的函数,即从数组中删除该监听函数
  45. return function unsubscribe() {
  46. if(!isSubscribe) {
  47. return // 如果已经取消订阅过了,直接返回
  48. }
  49. isSubscribe = false
  50. // 从下一轮的监听函数数组(用于下一次dispatch)中删除这个监听器。
  51. const index = nextListeners.indexOf(listener)
  52. nextListeners.splice(index, 1)
  53. }
  54. }
  55. function dispatch(action) {
  56. //调用reducer,得到新state
  57. currentState = currentReducer(currentState, action);
  58. //更新监听数组
  59. currentListener = nextListener;
  60. //调用监听数组中的所有监听函数
  61. for(let i = 0; i < currentListener.length; i++) {
  62. const listener = currentListener[i];
  63. listener();
  64. }
  65. }

bindActionCreators

combineReducers

  1. function combineReducers(reducers) {
  2. //先获取传入reducers对象的所有key
  3. const reducerKeys = Object.keys(reducers)
  4. const finalReducers = {} // 最后真正有效的reducer存在这里
  5. //下面从reducers中筛选出有效的reducer
  6. for(let i = 0; i < reducerKeys.length; i++){
  7. const key = reducerKeys[i]
  8. if(typeof reducers[key] === 'function') {
  9. finalReducers[key] = reducers[key]
  10. }
  11. }
  12. const finalReducerKeys = Object.keys(finalReducers);
  13. //这里assertReducerShape函数做的事情是:
  14. // 检查finalReducer中的reducer接受一个初始action或一个未知的action时,是否依旧能够返回有效的值。
  15. let shapeAssertionError
  16. try {
  17. assertReducerShape(finalReducers)
  18. } catch (e) {
  19. shapeAssertionError = e
  20. }
  21. //返回合并后的reducer
  22. return function combination(state= {}, action){
  23. //这里的逻辑是:
  24. //取得每个子reducer对应的state,与action一起作为参数给每个子reducer执行。
  25. let hasChanged = false //标志state是否有变化
  26. let nextState = {}
  27. for(let i = 0; i < finalReducerKeys.length; i++) {
  28. //得到本次循环的子reducer
  29. const key = finalReducerKeys[i]
  30. const reducer = finalReducers[key]
  31. //得到该子reducer对应的旧状态
  32. const previousStateForKey = state[key]
  33. //调用子reducer得到新状态
  34. const nextStateForKey = reducer(previousStateForKey, action)
  35. //存到nextState中(总的状态)
  36. nextState[key] = nextStateForKey
  37. //到这里时有一个问题:
  38. //就是如果子reducer不能处理该action,那么会返回previousStateForKey
  39. //也就是旧状态,当所有状态都没改变时,我们直接返回之前的state就可以了。
  40. hasChanged = hasChanged || previousStateForKey !== nextStateForKey
  41. }
  42. return hasChanged ? nextState : state
  43. }
  44. }

applyMiddleWare

  1. function applyMiddleware(...middlewares) {
  2. // 返回一个函数A,函数A的参数是一个createStore函数。
  3. // 函数A的返回值是函数B,其实也就是一个加强后的createStore函数,大括号内的是函数B的函数体
  4. return createStore => (...args) => {
  5. //用参数传进来的createStore创建一个store
  6. const store = createStore(...args)
  7. //注意,我们在这里需要改造的只是store的dispatch方法
  8. let dispatch = () => { //一个临时的dispatch
  9. //作用是在dispatch改造完成前调用dispatch只会打印错误信息
  10. throw new Error(`一些错误信息`)
  11. }
  12. //接下来我们准备将每个中间件与我们的state关联起来(通过传入getState方法),得到改造函数。
  13. const middlewareAPI = {
  14. getState: store.getState,
  15. dispatch: (...args) => dispatch(...args)
  16. }
  17. //middlewares是一个中间件函数数组,中间件函数的返回值是一个改造dispatch的函数
  18. //调用数组中的每个中间件函数,得到所有的改造函数
  19. const chain = middlewares.map(middleware => middleware(middlewareAPI))
  20. //将这些改造函数compose(翻译:构成,整理成)成一个函数
  21. //用compose后的函数去改造store的dispatch
  22. dispatch = compose(...chain)(store.dispatch)
  23. // compose方法的作用是,例如这样调用:
  24. // compose(func1,func2,func3)
  25. // 返回一个函数: (...args) => func1( func2( func3(...args) ) )
  26. // 即传入的dispatch被func3改造后得到一个新的dispatch,新的dispatch继续被func2改造...
  27. // 返回store,用改造后的dispatch方法替换store中的dispatch
  28. return {
  29. ...store,
  30. dispatch
  31. }
  32. }
  33. }
  34. function compose(...funcs) {
  35. // 当未传入函数时,返回一个函数:arg => arg
  36. if(funcs.length === 0) {
  37. return arg => arg
  38. }
  39. // 当只传入一个函数时,直接返回这个函数
  40. if(funcs.length === 1) {
  41. return funcs[0]
  42. }
  43. // 返回组合后的函数
  44. return funcs.reduce((a, b) => (...args) => a(b(...args)))
  45. //reduce是js的Array对象的内置方法
  46. //array.reduce(callback)的作用是:给array中每一个元素应用callback函数
  47. //callback函数:
  48. /*
  49. *@参数{accumulator}:callback上一次调用的返回值
  50. *@参数{value}:当前数组元素
  51. *@参数{index}:可选,当前元素的索引
  52. *@参数{array}:可选,当前数组
  53. *
  54. *callback( accumulator, value, [index], [array])
  55. */
  56. }