<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <script type="text/javascript" src="./js/babel.js"></script>
    </head>
    <body></body>
</html>

<script>
    function compose(...funcs) {
        if (funcs.length === 0) {
            return (arg) => arg;
        }

        if (funcs.length === 1) {
            return funcs[0];
        }

        return funcs.reduce((a, b) => (...args) => a(b(...args)));
    }
    const loggerMiddleware = ({ getState, dispatch }) => (next) => (action) => {
        console.log(getState(), action.type, 'before');
        next(action);
        console.log(getState(), action.type, 'after');
    };
    const thunkMiddleware = ({ getState, dispatch }) => (next) => (action) => {
        if (typeof action === 'function') {
            return action({ getState, dispatch });
        } else {
            return next(action);
        }
    };
    function applyMiddleware(...middleWares) {
        return (createStore) => (reducer) => {
            const store = createStore(reducer);

            const chains = middleWares.map((m) =>
                m({
                    getState: store.getState,
                    dispatch: (action) => store.dispatch(action),
                })
            );

            const dispatch = compose(...chains)(store.dispatch);
            return {
                ...store,
                dispatch,
            };
        };
    }

    function createStore(reducer, enhancer) {
        if (typeof enhancer !== 'undefined' && typeof enhancer === 'function') {
            return enhancer(createStore)(reducer);
        }
        let currentState = 0;
        let currentListeners = []; // 监听器,可监听多个事件

        const getState = function () {
            return currentState;
        };

        const subscribe = (listener) => {
            currentListeners.push(listener);
        };

        const dispatch = (action) => {
            if (typeof action === 'function') {
                console.log('function action not support ');
                return;
            }
            currentState = reducer(currentState, action); // 覆盖原来的state
            currentListeners.forEach((listener) => listener());
        };
        // 尽量写得复杂,使不会与我们自定义的action有重复可能
        dispatch({ type: '@@redux/init' });
        return {
            getState,
            subscribe,
            dispatch,
        };
    }

    const defaultState = {
        value: 10,
    };
    function reducer(state = defaultState, action) {
        switch (action.type) {
            case 'add':
                return state + 1;
            // ...
            default:
                return state;
        }
    }

    // enhancer = applyMiddleware(loggerMiddleware);
    // const store = createStore(reducer, enhancer);

    const enhancer = applyMiddleware(loggerMiddleware, thunkMiddleware);
    const store = createStore(reducer, enhancer);

    //同步action, action是一個對象
    const add = () => ({ type: 'add' });
    store.dispatch(add());

    //同步action,action是一個函數
    const addAsyn = () => {
        return ({ dispatch, getState }) => {
            setTimeout(() => {
                dispatch(add());
            }, 5000);
        };
    };
    store.dispatch(addAsyn());

    // console.log(store);
</script>

  

posted on 2022-06-28 15:24  码农-编程小子  阅读(11)  评论(0编辑  收藏  举报