applyMiddleware() 源码分析

// 这个函数应该是整个源码中最难理解的一块了
// 该函数返回一个柯里化的函数
// 所以调用这个函数应该这样写 applyMiddleware(...middlewares)(createStore)(...args)
export default function applyMiddleware(...middlewares) {
  return createStore => (...args) => {
   // 这里执行 createStore 函数,把 applyMiddleware 函数最后次调用的参数传进来
    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.`
      )
    }
    let chain = []
    // 每个中间件都应该有这两个函数
    const middlewareAPI = {
      getState: store.getState,
      dispatch: (...args) => dispatch(...args)
    }
    // 把 middlewares 中的每个中间件都传入 middlewareAPI
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    // 和之前一样,从右至左调用每个中间件,然后传入 store.dispatch
    dispatch = compose(...chain)(store.dispatch)
    // 这里只看这部分代码有点抽象,我这里放入 redux-thunk 的代码来结合分析
    // createThunkMiddleware返回了3层函数,第一层函数接收 middlewareAPI 参数
    // 第二次函数接收 store.dispatch
    // 第三层函数接收 dispatch 中的参数
{function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
  // 判断 dispatch 中的参数是否为函数
    if (typeof action === 'function') {
    // 是函数的话再把这些参数传进去,直到 action 不为函数,执行 dispatch({tyep: 'XXX'})
      return action(dispatch, getState, extraArgument);
    }

    return next(action);
  };
}
const thunk = createThunkMiddleware();

export default thunk;}
// 最后把经过中间件加强后的 dispatch 于剩余 store 中的属性返回,这样你的 dispatch
    return {
      ...store,
      dispatch
    }
  }
}

猜你喜欢

转载自blog.csdn.net/zSY_snake/article/details/85318425
今日推荐