redux源码阅读——applyMiddleware

redux源码——applyMiddleware

相关源码展示

applyMiddleware源码

export default function applyMiddleware(...middlewares) {
  return (createStore) => (reducer, preloadedState, enhancer) => {
    var store = createStore(reducer, preloadedState, enhancer)
    var dispatch = store.dispatch
    var chain = []

    var middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    }
    // ### step1
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    // ### step2
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

compose函数源码

export default function compose(...funcs) {
  if (funcs.length === 0) {
    return arg => arg
  }

  if (funcs.length === 1) {
    return funcs[0]
  }

  const last = funcs[funcs.length - 1]
  const rest = funcs.slice(0, -1)
  // ### step3
  return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))
}

redux-thunk源码

function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }

    return next(action);
  };
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;

初始化调用部分的代码

import thunk from 'redux-thunk'
import createLogger from 'redux-logger'
import reducer from './reducers'

const middleware = [ thunk ]
if (process.env.NODE_ENV !== 'production') {
  middleware.push(createLogger())
}

const store = createStore(
  reducer,
  applyMiddleware(...middleware)
)

action中调用的代码

const fetchPosts = reddit => dispatch => {
  dispatch(requestPosts(reddit))
  return fetch(`https://www.reddit.com/r/${reddit}.json`)
    .then(response => response.json())
    .then(json => dispatch(receivePosts(reddit, json)))
}

源码分析

做了什么

就是在原先同步dispatch action这条路上,根据middleware加入了一层一层的处理,而对于redux-thunk,其实就是将异步的action的返回替换为同步的action返回,先返回一个start的action,然后等resolve了之后,再返回一个resolve的action

step1

剥离middleware的第一层,拿redux-thunk举例,剥离之后,应该是这样的

next => action => {
 if (typeof action === 'function') {
    return action(dispatch, getState, extraArgument);
  }

  return next(action);
};

step2 & step3

这两段是为了将每个middleware再次剥离之后,然后再套起来,类似俄罗斯套娃那样,比如两个middleware是这样的[thunk, logger],那么经过这两段代码处理之后,thunk的next就是logger,logger的next就是原先的dispatch(store.dispatch)

你可能感兴趣的:(redux源码阅读——applyMiddleware)