пятница, 8 февраля 2019 г.

Redux.js - простые примеры устройства.

// Устройство функции createStore() 

const defaultState = {
    counter: 0
};

function createUpAction (value) {
    return {
        type: 'UP',
        value: value
    };
}

function counterReducer (state = defaultState, action) {
  const stateCopy = lodash.cloneDeep(state);
  switch (action.type) {
    case 'UP':
      stateCopy.counter += action.value;
      return stateCopy;
    case 'DOWN':
      stateCopy.counter -= action.value
      return stateCopy;
    default:
      return state;
  }
}

const store = createStore(counterReducer);

store.dispatch(createUpAction(1));
store.getState(); // {counter: 1}

function createStore (reducer, initialState) {
    let state = initialState;
    return {
        dispatch: (action) => {state = reducer(state, action);},
        getState: () => {return state;}
    }
}


Устройство функции combineReducers()

const reducer = combineReducers({
  todoState: todoReducer,
  counterState: counterReducer
})

function counterReducer (state, action) {
  if (action.type === 'ADD') {
        return state + 1;
  } else {
        return state;
  }
}

const initialState = {
    todoState: [],
    counterState: 0,
}

const store = createStore(reducer, initialState);

function combineReducers (reducersMap) {
    return function combinationReducer (state, action) {
        const nextState = {};
        Object.entries(reducersMap).forEach(([key, reducer]) => {
              nextState[key] = reducer(state[key], action);
        });
        return nextState;
    }
}



Устройство функции applyMiddleware()

const createStoreWithMiddleware = applyMiddleware(someMiddleware)(createStore);

const store = createStoreWithMiddleware(reducer, initialState);

const thunk = (store) => (dispatch) => (action) => {
  if (typeof action === 'function') {
        return action(store.dispatch, store.getState);
  }
  return dispatch(action);
}

function createStore (reducer, initialState) {
    let state = initialState;
    return {
        dispatch: (action) => {state = reducer(state, action);},
        getState: () => {return state;}
    }
}

function applyMiddleware (middleware) {
  return function createStoreWithMiddleware (createStore) {
    return (reducer, state) => {
      const store = createStore(reducer, state);

      return {
        dispatch: action => middleware(store)(store.dispatch)(action),
        getState: store.getState
      }
    }
  }
}

Rx.js - простые примеры.

Примеры работы библиотеки Rx.

Пример заполнения потока данными.

// Обработчик данных в потоке.
const observer = {
  next: value => console.log(value), // 1, 2
  error: error => console.error(error), //
  complete: () => console.log("completed") // completed
};

// Заполнитель потока данными.
const observable = new Observable(observer => {
  observer.next(1);
  observer.next(2);
  observer.complete();
})

// Связывания обработчика данных с заполнителем потока данными.
observable.subscribe(observer);


Пример заполнения потока данными и отписки от потока.

// Обработчик данных в потоке.
const observer = {
  next: value => console.log(value), // 0, 1, 2, 3, 4
};

// Заполнитель потока данными, возвращающий функцию отписки, вызов которой останавливает добавление данных в поток данных.
const timer = new Observable(observer => {
  let counter = 0; //объявляем счетчик
  const intervalId = setInterval(() => {
    observer.next(counter++); // передаем значение счетчика наблюдателю и увеличиваем его на единицу
  }, 1000);

  return () => {
    clearInterval(intervalId);
  }
});

// Связывания обработчика данных с заполнителем потока данными с возвратом функции отписки, вызов которой остановит добавление данных в поток данных.
const  timerSubscription = timer.subscribe(observer);

// Остановка через некоторое время заполнение потока данными с помощью функции отписки.
setTimeout(() => timerSubscription.unsubscribe(), 5000); // поток завершиться через 5 секунд из-за выполненного clearInterval(intervalId)