// 这个函数应该是整个源码中最难理解的一块了
// 该函数返回一个柯里化的函数
// 所以调用这个函数应该这样写 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
}
}
}
applyMiddleware() 源码分析
猜你喜欢
转载自blog.csdn.net/zSY_snake/article/details/85318425
今日推荐
周排行