- 实现createStore、getState、subscribe、dispatch
export function createStore(reducer, enhancer){
let currentState = undefined;
let currentListeners = [];
//提供getState方法
function getState(){
return currentState
}
//订阅方法: 把订阅函数 push到 数组中
function subscribe(listener){
currentListeners.push(listener)
}
//更新方法: 就是执行reducer 顺便把订阅方法都执行了
function dispatch(action){
currentState = reducer(currentState, action)
currentListeners.forEach(v=>v())
return action
}
// 第一次设置下默认值, 设置一个不太可能会写在reducer里面的值
dispatch({type:'@impossible/Type@'})
return {
getState,
subscribe,
dispatch
}
}
-
中间件实现
核心就是按顺序执行中间件函数, 接下来从最终使用开始倒推实现
- 使用:
const store = createStore(counterReducer, applyMiddleware([ thunk, logger]))
-
createStore 传入enhancer
//如果有中间件来加强 就走入中间件的逻辑 if(enhancer) { return enhancer(createStore)(reducer) }
-
实现applyMiddleware
export function applyMiddleware(middlewares) { return createStore => (...args) => { //第一步先创建好原来的store const store = createStore(...args) let dispatch = store.dispatch const midApi = { getState: store.getState, dispatch:(...args)=>dispatch(...args) } // 将所有的中间件执行一次 返回数组 dispatch => action =>{} const middlewareChain = middlewares.map(middleware => middleware(midApi)) // compose 将数组的 dispatch => action =>{} 转换成一个 dispatch => action =>{} // 执行传入 dispatch 得到新的dispatch dispatch = compose(middlewareChain)(store.dispatch) return { ...store, dispatch } } } function compose(funcs) { if(funcs.length == 1) { return funcs[0] } return funcs.reduce((left,right) => ((...args) => right(left(...args)))) }
-
约定中间件: 所有的中间件都需要执行三次
- 第一次 传入 dispatch, getState 供某些特殊中间件使用
- 第二次 传入 dispatch 为了链接其他中间件
- 第三次 传入 action, 真正执行中间件代码, 使用第二次传入的dispatch 按顺序执行下一个中间件
function logger({dispatch, getState}) { return dispatch => action => { // 中间件任务 console.log(action.type + '执行了!!'); // 下一个中间件 return dispatch(action); } } function thunk({dispatch, getState}) { return dispatch => action => { if (typeof action == 'function') { return action(dispatch, getState) } return dispatch(action) } }