Redux 源码自己写了一遍

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title>Test</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
    </head>
    <body>
      <script type='text/javascript'>
        // var f = function( ...arg ){
        //     arg 是个数组
        //     ...arg 是传递进来的原封不动的值
        // }

        // const reducer = function(state, action){
        //   if(!state){
        //     state = initialState;
        //   }
        //   let nextState = _.deepClone(state);

        //   switch(action.type){
        //     case 'ADD_TODO':
        //       nextState.todos.push( action.payload );
        //       break;
        //     case 'INCREASE':
        //       nextState.counter = nextState.counter++;
        //       break;
        //     default:
        //       break;
        //   }

        //   return nextState;
        // }


        /*** compose ***/
        // compose(func3, func2, func1)(0);
        // 相当于写了 func3( func2( func1(0) ) )
        const compose = function( ...funcs ) {
          // 若没有传递参数, 则直接返还1个函数
          if ( funcs.length === 0 ) {
            return arg => arg;
          }

          // 若只有1个参数, 则直接返还这个函数
          if ( funcs.length === 1 ) {
            return funcs[0];
          }

          // 取出最后1个函数 当作 reduceRight的第2个参数
          const last = funcs[funcs.length - 1];
          // 取除了最后一个函数以外的函数数组
          const rest = funcs.slice(0, -1);
          // 所传递进来的参数 都当作 最后1个函数的参数
          return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args))
        }

        /*** combineReducers ***/
        const combineReducers = function(obj){
          return function(state, action){
            // nextState 为返回的新 state
            let nextState = {};
            for(var item in obj){
              // obj[item] 为item 对应的reducer
              /*
                state[item] 的意思是 state 对应与 item 上的值,
                比如 state 为 { counter: 0}, state[item]的值就为 0
              */
              nextState[item] = obj[item]( state[item], action );
            }
            return nextState;
          }
        }

        /*** bindActionCreators ***/
        const bindActionCreators = (obj, dispatch) => {
          let objNew = {};
          for(let i in obj){
            // item 为创建 action 的函数
            let item = obj[i];
            objNew[i] = (...args) => {
              dispatch( item(...args) );
            }
          }
          return objNew;
        }

        /*** applyMiddleware ***/
        // 传入所有的中间件
        const applyMiddleware = (...middlewares) => {
          // 可以传入 createStore 作为参数
          return (createStore) => {
            // 这一步已经生成了 增强版本的 createStore
            return (reducer, initialState, enhancer) => {
              
              let store = createStore(reducer, initialState, enhancer);

              // 这一步原来的写法是
              // let chain = middlewares.map( middleware => middleware(store) );
              // 源代码里是 从新创建了一个store
              let storeNew = {
                getState: store.getState,
                dispatch: (action) => dispatch(action)
              }
              let chain = middlewares.map( middleware => middleware(storeNew) );

              // 只有最后1个函数的传入了 store.dispatch 当作 dispatch,
              // 其它函数都是最后1个函数的返回值当作 dispatch
              const dispatch = compose(...chain)(store.dispatch);

              /*
                最早本来想下面那样写,
                这个结果是所有中间件的 dispatch 都为 store.dispach

                let chain = [...middlewares].map( (item) => {
                  return item(store)(store.dispatch);
                } );

                const dispatch = (action) => {
                  compose(...chain)(action);
                };
                
                打印的结果为:

                3 dispatch before
                3 dispatch after
                2 dispatch before
                2 dispatch after
                1 dispatch before
                1 dispatch after
                
              */

              return {
                getState: store.getState,
                subscribe: store.subscribe,
                replaceReducer: store.replaceReducer,
                dispatch: dispatch
              }
            }
          }
        }

        /*** createStore ***/
        const createStore = function(reducer, initialState, enhancer){
          if( typeof enhancer === "function"){
            return enhancer(createStore)(reducer, initialState);
          }

          let state = initialState;
          // 操作的 listeners
          let listeners = [];
          let listenersCache = listeners;

          // 但凡 listeners 有变化, 比如push了 或者删除了, 都提前执行下 ensure
          const ensure = function(){
            // 若相等, 则拷贝一个新的 listeners
            if( listeners == listenersCache ){
              listeners = listenersCache.slice();
            }
          }

          const getState = function(){
            return state;
          }

          const dispatch = function(action){
            state = reducer(state, action);

            // 为了让 ensure 执行成功
            listenersCache = listeners;
            let len = listenersCache.length;
            for(let i = 0; i < len; i++){
              listenersCache[i]();
            }

            return action;
          }

          const subscribe = listener => {
            ensure();
            listeners.push(listener);

            return function(){
              ensure();
              listeners = listeners.filter(function(item, i){
                return item != listener;
              });
            }

          }

          dispatch({});
          return {
            dispatch: dispatch,
            getState: getState,
            subscribe: subscribe
          }
        }

        const initialState = {
          counter: 0,
          todos: []
        }

        const counterReducer = function(counter = 0, action){
          switch(action.type){
            case 'INCREASE':
              console.log('Reducer increase');
              return counter = counter + 1;
            default:
              return counter;
          }
        }

        const todosReducer = function(todos = [], action){
          switch(action.type){
            case 'ADD_TODO':
              return [...todos, action.payload];
            default:
              return todos;
          }
        }

        const rootReducer = combineReducers({
          counter: counterReducer,
          todos: todosReducer
        });

        
        const actionAdd = (n) => {
          return {type: n}
        }

        const store = createStore(rootReducer, initialState);

        const actionCreate = bindActionCreators(
          {actionAdd: actionAdd},
          store.dispatch
        );

        store.subscribe(function(){
          console.log( store.getState() );
        });

        store.dispatch( actionAdd('INCREASE') );
        actionCreate.actionAdd('INCREASE');
        store.dispatch({type: 'ADD_TODO', payload: 'hello world'});

        console.log(' ---------- 分割线 ---------- ');

        // 中间件 1
        // 根据源代码 middlewareAPI 是一个新的对象, 类似 store
        // 只有store 里的dispatch 和 getState方法
        const middleware1 = ( middlewareAPI ) => {
          return (dispatch) => {
            return (action) => {
              console.log( '1 dispatch before' );

              // 这个 dispatch 其实是 middleware2 里的函数 (action) => {...}
              let actionReturn = dispatch(action);

              console.log( '1 dispatch after' );
              return actionReturn;
            }
          }
        };

        const middleware2 = ( middlewareAPI ) => {
          return (dispatch) => {
            return (action) => {
              console.log( '2 dispatch before' );

              // 这个 dispatch 其实是 middleware3 里的函数 (action) => {...}
              let actionReturn = dispatch(action);

              console.log( '2 dispatch after' );
              return actionReturn;
            }
          }
        };

        const middleware3 = ( middlewareAPI ) => {
          return (dispatch) => {
            return (action) => {
              console.log( '3 dispatch before' );

              // 这个 dispatch 才是 store.dispatch, 最终只有这里调用 reducer 更新
              let actionReturn = dispatch(action);

              console.log( '3 dispatch after' );
              return actionReturn;
            }
          }
        };

        let enhancedCreateStore = applyMiddleware(middleware1, middleware2, middleware3)(createStore);
        let storeEnhance = enhancedCreateStore(rootReducer, initialState);

        /*
          最后的打印结果是:

          1 dispatch before
          2 dispatch before
          3 dispatch before
          Reducer increase
          3 dispatch after
          2 dispatch after
          1 dispatch after
        */
        storeEnhance.dispatch({type: 'INCREASE'});

      </script>
    </body>
</html>
原文地址:https://www.cnblogs.com/zhengming2016/p/6770486.html