Bläddra i källkod

HW<13>start logic

Gennadysht 2 år sedan
förälder
incheckning
88b76d3dfc
1 ändrade filer med 99 tillägg och 0 borttagningar
  1. 99 0
      js/HW_13_kiosk/index.html

+ 99 - 0
js/HW_13_kiosk/index.html

@@ -0,0 +1,99 @@
+<header>KIOSK</header>
+
+<body>
+    <script>
+        function createStore(reducer) {
+            let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
+            let cbs = []                     //массив подписчиков
+
+            const getState = () => state            //функция, возвращающая переменную из замыкания
+            const subscribe = cb => (cbs.push(cb),   //запоминаем подписчиков в массиве
+                () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
+
+            const dispatch = action => {
+                const newState = reducer(state, action) //пробуем запустить редьюсер
+                if (newState !== state) { //проверяем, смог ли редьюсер обработать action
+                    state = newState //если смог, то обновляем state 
+                    for (let cb of cbs) cb() //и запускаем подписчиков
+                }
+            }
+
+            return {
+                getState, //добавление функции getState в результирующий объект
+                dispatch,
+                subscribe //добавление subscribe в объект
+            }
+        }
+        const seller = (state, { type, item, amount, cash, price }) => {
+            if (state === undefined) {
+                state = {
+                    beer: { amount: 20, price: 10 },
+                    vodka: { amount: 10, price: 30 },
+                    cigars: { amount: 100, price: 20 },
+                    cashbox: 0,
+                }
+            }
+            if (type === 'BUY' &&
+                item in state &&
+                typeof amount == "number" &&
+                typeof cash == "number" &&
+                state[item].amount >= amount &&
+                amount > 0 &&
+                cash > 0 &&
+                state[item].price <= cash / amount) { //если тип action - КУПИТЬ, то:
+                /*let newState = {...state};
+                newState[item] =  state[item].amount - amount;
+                newState.cashbox = state.cashbox + amount * price;
+                return newState;*/
+                return {
+                    ...state, //берем все что было из ассортимента
+                    [item]: { amount: state[item].amount - amount, price: state[item].price },  //и уменьшаем то, что покупается на количество
+                    cashbox: state.cashbox + amount * state[item].price,
+                }
+            }
+            if (type === 'SUPPLY' &&
+                typeof amount == "number" && amount > 0) {
+                let newState = { ...state };
+                let currItem = newState[item];
+                if (!currItem) {
+                    if (typeof price != "number" || price <= 0)
+                        return state;
+                    newState[item] = { amount: 0, price: price };
+                }
+                else if (!(price === undefined))
+                    return state;
+                newState[item] = { amount: newState[item].amount + amount, price: newState[item].price };  //и уменьшаем то, что покупается на количество
+                return newState;
+            }
+            return state;
+        }
+        let store = createStore(seller);
+        const unsubscribe = store.subscribe(() => console.log(store.getState()))
+
+        store.dispatch({ type: 'BUY', item: 'cigars', amount: 3, cash: 58 })
+        store.dispatch({ type: 'BUY', item: 'vodka', amount: 3, cash: 92 })
+        store.dispatch({ type: 'SUPPLY', item: 'vodka', amount: 5 })
+        store.dispatch({ type: 'SUPPLY', item: 'cukerky', amount: 5, price: 3 })
+
+
+    </script>
+</body>
+
+const store = createStore(reducer)
+
+//запомнит функцию во внутреннем массиве cbs.
+//она будет запущена при любом успешном dispatch
+const unsubscribe = store.subscribe(() => console.log(store.getState()))
+
+setTimeout(unsubscribe, 10000) //отпишемся через 10 секунд, например
+
+//происходит запуск редьюсера, который создает новый state.
+//dispatch запускает всех подписчиков из массива cbs
+store.dispatch({type: 'КУПИТЬ', ШО: 'пиво', СКОКА: 3})
+
+const купиПиваса = СКОКА => ({type: 'КУПИТЬ', ШО: 'пиво', СКОКА})
+const купиЧипсики = СКОКА => ({type: 'КУПИТЬ', ШО: 'чипсы', СКОКА})
+
+store.dispatch(купиПиваса(3))
+store.dispatch(купиЧипсики(6))
+store.dispatch(купиПиваса(30))