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 в объект } } function reducer(state, {type, ШО, СКОКА, БАБЛО}){ if (!state){ return { пиво: {count: 100, price: 50}, чипсы: {count: 100, price: 32}, сиги: {count: 100, price: 70}, касса: 0, } } if (type === 'КУПИТЬ'){ if (ШО in state && БАБЛО > state[ШО].price * СКОКА && СКОКА <= state[ШО].count){ return { ...state, [ШО]: {count: state[ШО].count - СКОКА, price: state[ШО].price}, касса: +state.касса + (СКОКА * state[ШО].price), } } } return state } const store = createStore(reducer) for (let good of Object.entries(store.getState())) { if (good[0] !== 'касса') { let listOption = document.createElement('option'); listOption.textContent = good[0]; goods.append(listOption); } } const buys = (product, count, money) => ({type: 'КУПИТЬ', ШО: product, СКОКА: count, БАБЛО: money}); buy.onclick = () => { store.dispatch(buys(goods.value, quantity.value, money.value)); } const unsubscribe = store.subscribe(() => console.log(store.getState())) function product(){ for (let good of Object.entries(store.getState())) { if (good[0] !== 'касса') { let h1 = document.createElement('h1'); shop.append(h1); store.subscribe(() => h1.innerText = `${good[0]}: количество ${store.getState()[good[0]].count}, цена: ${store.getState()[good[0]].price}`); h1.innerText = `${good[0]}: количество ${store.getState()[good[0]].count}, цена ${store.getState()[good[0]].price}`; } } } function casa(){ const h1 = document.createElement('h1'); shop.append(h1); store.subscribe(() => h1.innerText = `Денег в кассе = ${store.getState().касса}`); h1.innerText = `Денег в кассе = ${store.getState().касса}`; } product() casa();