redux核心代码初步实现

/** * createStore(reducer,preloadedState预存储状态,enhancer对store功能进行增强) * { *getState,dispatch,subscribe * } */function createStore(reducer, preloadedState, enhancer) { // 9,约束reducer参数类型 if (typeof reducer !== "function") throw new Error("reducer must be a function"); // 12判断enchancer是否传递,是否是一个函数 if (typeof enhancer !== "undefined") { if (typeof enhancer !== "function") { throw new Error("enhancer must be a function"); } // redux中调用,传入createStore 并返回一个函数,返回reducer, preloadedState return enhancer(createStore)(reducer, preloadedState); }// 1,sotre对象中存储的状态 var currentState = preloadedState; // 6,存放订阅者函数 var currentListeners = []; //2,获取状态 function getState() { return currentState; } // 3用于触发action的方法 function dispatch(action) { // 10,判断action是否是一个对象 if (!isPlainObject(action)) throw new Error("action必须是一个对象"); // 11,判断action中的type属性是否存在 if (typeof action.type === "undefined") throw new Error("action对象中必须有type属性"); currentState = reducer(currentState, action); // 根据当前状态和action处理返回新的状态 // 7循环数组调用订阅者 for (let i = 0; i < currentListeners.length; i++) { // 获取订阅者 var listener = currentListeners[i]; // 调用订阅者 listener(); } }// 5,订阅状态 function subscribe(listener) { currentListeners.push(listener); }//8 返回 return { getState, dispatch, subscribe, }; }// 4 // store.subscribe(() => {}); // 判断参数是否是对象类型 // 判断对象的当前原型对象是否和顶层原型对象相同 function isPlainObject(obj) { // 排除基本数据类型和null if (typeof obj !== "object" || obj === null) return false; // 区分数组和对象 原型对象对比的方式 var proto = obj; // 获取最顶层的原型对象 while (Object.getPrototypeOf(proto) !== null) { proto = Object.getPrototypeOf(proto); } return Object.getPrototypeOf(obj) === proto; // 返回true就是对象 }function applyMiddleware(...middlewares) { return function (createStore) { return function (reducer, preloadedState) { // 创建store,拿到store,给中间件传参 var store = createStore(reducer, preloadedState); // 阉割版的 store var middlewareAPI = { getState: store.getState, dispatch: store.dispatch, }; // 调用中间件的第一层函数 传递阉割版的store对象,返回中间件函数内的里面两层函数 var chain = middlewares.map((middleware) => middleware(middlewareAPI)); //中间件第二层参数传参,第三层就是dispath var dispatch = compose(...chain)(store.dispatch); // 返回一个增强版的store return { ...store, dispatch, }; }; }; }function compose() { var funcs = [...arguments]; console.log(funcs); // 因为函数嵌套问题,执行顺序虽然是logger再thunk,为了保证顺序,要倒叙数组,先执行thunk第二层返回dispath, return function (dispatch) { for (var i = funcs.length - 1; i >= 0; i--) { // 第一轮执行返回值返回是thunk里面的函数,他是logger需要的 dispatch = funcs[i](dispatch); } return dispatch; }; }// bindActionCreators函数将action creator函数转换为能够触发action的函数 function bindActionCreators(actionCreators, dispatch) { // 创建一个对象用于返回,返回值是一个对象 // function increment(){ //dispatch({type:'increment'}) // } var boundActionCreators = {}; for (var key in actionCreators) { // IIFE解决key变量不能保存的问题 (function (key) { boundActionCreators[key] = function () { dispatch(actionCreators[key]()); }; })(key); // actionCreators[key]()拿到increment函数,执行,返回action对象 // dispatch(actionCreators[key]())dispatch action对象 } return boundActionCreators; }// combineReducers组合小的reducer成为大的reducer,返回一个reducer函数 function combineReducers(reducers) { //检查reducer类型 它必须是函数 var reducerKeys = Object.keys(reducers); for (var i = 0; i < reducerKeys.length; i++) { var key = reducerKeys[i]; if (typeof reducers[key] !== "function") throw new Error("reducer必须是函数"); }// 调用一个一个的小的reducer 将每一个小的reducer中返回的状态存储在一个新的大的对象中 return function (state, action) { var nextState = {}; // 存储最新的状态 // 循环reducer拿到最新的状态 for (var i = 0; i < reducerKeys.length; i++) { var key = reducerKeys[i]; var reducer = reducers[key]; var previousStateForKey = state[key]; nextState[key] = reducer(previousStateForKey, action); } console.log(nextState) return nextState; }; }

【redux核心代码初步实现】测试代码
Document - 锐客网 0

    推荐阅读